题目链接:704. 二分查找
最基本的二分查找搜索目标数值问题。
二分法适用条件:无重复元素、按照大小关系排序。
易错点
在二分查找问题中由于区间开闭与左右指针更新方式不匹配导致程序出现问题。
二分查找:
循环条件为left < right
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size();
while(left < right){
int middle = left + (right - left) / 2; //防止溢出。
if(nums[middle] < target) {
left = middle + 1;
}
else if (nums[middle] > target) {
right = middle;
}
else{
return middle;
}
}
return -1;
}
};
二分查找:
循环条件为left <= right
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while(left <= right){
int middle = left + (right - left) / 2;
if(nums[middle] < target) {
left = middle + 1;
}
else if (nums[middle] > target) {
right = middle - 1;
}
else{
return middle;
}
}
return -1;
}
};
总结:
开区间指针在更新时middle值需要保留在二分查找范围内,闭区间指针在更新时middle值不再接下来二分查找范围内需要舍弃。
题目连接:27.移除元素
在数组在内存中以连续的地址存储元素,删除某一元素时需要用之后的元素覆盖之前的元素来实现。
双指针求解:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
vector<int>::iterator iter1 = nums.begin(), iter2 = nums.begin();
int len = nums.size();
while(iter1 < nums.end()) {
if (*iter1 != val){
*iter2 = *iter1;
iter2++;
iter1++;
}
else {
iter1++;
len--;
}
}
return len;
}
};
iter1 为快指针用用来检查所指的num是否等于val, iter2为慢指针作用为向修改之后的容器内部增加f符合条件的新元素。