算法训练营 第一天:二分查找与移除元素
二分查找
二分查找要注意左闭右开和走闭右闭的两种写法,个人认为,左闭右开的写法应该会更常用,因为左闭右开时,它的right正好是数组的size,符合代码思维。
- 左闭右开
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
while(left<right){
int middle = left+(right-left)/2;//这里注意避免超过int的阈值,所以没有用(right+left)/2
if(nums[middle] == target)
return middle;
else if(nums[middle]<target)
left = middle+1;
else
right = middle;
}
return -1;
}
};
- 左闭右闭
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
while(left<=right){
int middle = left+(right-left)/2;//这里注意避免超过int的阈值,所以没有用(right+left)/2
if(nums[middle] == target)
return middle;
else if(nums[middle]<target)
left = middle+1;
else
right = middle-1;
}
return -1;
}
};
移除元素
移除元素的重点是不能创建新的数组,因此采用双指针的写法,快指针碰到等于target的元素就continue,否则就把当前的值赋给慢指针。
这里考虑如果用STL内置函数,比如erase,remove,需要知道这些内置函数的复杂度。
vector.erase()时间复杂度:O(n)
vector.remove()时间复杂度:O(n)
注:remove()函数需要和erase函数搭配使用,这里移除元素的解题思路就是remove函数的实现思路。