704.二分查找
文档讲解:代码随想录
视频讲解:手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili
题目链接:. - 力扣(LeetCode)
解题思路:
二分查找方法不必赘述,用代码实现的思路为:创建left、right和middle的变量,初始值分别为数组最左边和最右边的下标,middle的值为left加right的一半(middle也是下标)。后续while循环条件是left与right的大小判断,循环内容为需要查找的值target和数组中middle下标对应的值的大小判断。
- 时间复杂度:O(log n)。每次循环查找时间减半,因此log n
- 空间复杂度:O(1)
关键点:
1.在最开始时需要设定好查找区间取值范围形式,在循环中每次取半后的区间取值形式要和最开始统一。有[left,right]、[left,right)和(left,right]三种,分别对应左闭右闭,左闭右开和左开右闭。其中左开右闭写法不常见。(个人见解:统一取值范围形式与否不会影响解题,而主要是便于理清代码思路,如果最开始是左闭右闭区间形式,后续却是左闭右开形式,这样不方便理解代码。)
2.不同的区间取值范围形式,对应的初始下标、while循环判断条件和赋值操作都略有不同。
c++代码:
1.左闭右闭写法
class Solution
{
public:
int search(vector<int>& nums, int target)
{ //左闭右闭写法
int left = 0;//左边起始下标
int right = nums.size() - 1; //右边起始下标
int middle;
//开始循环进行二分查找
while(left <= right)
{
middle = (left + right) / 2;
if(nums[middle] > target)
{
right = middle - 1;
}
else if(nums[middle] < target)
{
left = middle + 1;
}
else
{
return middle;
}
}
return -1;
}
};
对左闭右闭写法区间重新取值的个人见解:左闭右闭写法中,right和left的取值是等于middle还是middle加减1都可以,让left、right取值等于middle是偷懒的写法但在数学逻辑上不严谨,存在对重复元素的判断。
2.左闭右开写法
两种写法不同之处在注释中提及。
class Solution
{
public:
int search(vector<int>& nums, int target)
{ //左闭右开写法
int left = 0;
int right = nums.size(); //右边起始下标初始值不同,是数组大小而非数组大小减1
int middle;
while(left < right) //循环条件不同,为小于而非小于等于
{
middle = (left + right) / 2;
if(nums[middle] > target)
{
right = middle; //right赋值为middle而非middle-1
}
else if(nums[middle] < target)
{
left = middle + 1;
}
else
{
return middle;
}
}
return -1;
}
};
27.移除元素
文档讲解:代码随想录
视频讲解:数组中移除元素并不容易! | LeetCode:27. 移除元素_哔哩哔哩_bilibili
题目链接:. - 力扣(LeetCode)
解题思路:
1.双重for循环暴力破解。一层for循环遍历数组查找需要删除的值,第二层for循环更新数组。(本文暂不继续说明此方法)
- 时间复杂度:O(n^2)。双重循环,故n^2
- 空间复杂度:O(1)
2.双指针。定义快指针fast和慢指针slow,快指针fast从0开始遍历数组寻找不需要删除的值,慢指针slow从0开始更新数组生成删除指定元素后的新数组。
- 时间复杂度:O(n)。一层循环,执行时间t与输入n呈线性关系,故n
- 空间复杂度:O(1)
关键点:
1.对数组的理解。数组在定义后在内存中大小是固定不变的,所谓的删除操作都是覆盖操作。不同的编程语言会对数组进行封装,如c++中的erase方法删除元素并自动使数组size减少,其本质还是覆盖操作并改变计数器的值。
c++代码:
1.整形形式快指针慢指针。
class Solution
{
public:
int removeElement(vector<int>& nums, int val)
{
int fast = 0; // 快指针
int slow = 0; // 慢指针
for(fast;fast < nums.size();fast++)
{
if(nums[fast] != val)
{
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
};
本文详细解析了二分查找算法的实现思路,包括左闭右闭和左闭右开两种区间取值方式,并对比了它们的时间和空间复杂度。同时介绍了数组中移除元素的两种方法:暴力破解和双指针优化,以及C++代码示例。

1628

被折叠的 条评论
为什么被折叠?



