1.力扣704 二分查找
方法1:二分查找判断目标值
代码:
class Solution { public: int search(vector<int>& nums, int target) {
int l = 0,r = nums.size() - 1;
while(l < r) {
int mid = (l + r) / 2;//
if(nums[mid] >= target) r = mid;
else l = mid + 1; }
if(nums[l] != target) return -1;
while(l < r) {
int mid = (l + r + 1) / 2;
if(nums[mid] <= target) l = mid;
else r = mid - 1; }
return l;
}
};
图片整理:
1.当区间为左闭右开,此时mid = (l+r)/2,当mid满足红色区域的性质时,根据target的大小,更新对应的左右区间
2.当区间为左闭右闭,当r和l隔得很近,mid采用向下取整可能会导致死循环,因此采用上取整mid=(l+r+1)/2,并根据mid的性质,更新对应的区间大小。
方法2:双指针逼近目标值
代码:
class Solution {
public:
int search(vector<int>& nums, int target) {
int l = 0,r = nums.size() - 1;//左指针,右指针
while(l < r)
{
if(nums[l] < target) l++;//如果左边的数小于目标值,说明需要往右逼近
else if(nums[r] > target) r--;//反之,往左逼近
}
if(l == r && nums[l] == target) return l; //如果l=r,并且数值等于目标值,说明逼近到目标值
else return -1;
}
};
2.力扣27移除元素
方法1.对撞指针
思路:
1.采用双指针,左边为l=0,右边为r=num.size()
2.由于标准答案右边是空的,因此考虑从l=0开始判断
3.判断当l=0时是否等于val,如果相等则把最后一个元素给l=0,然后重复判断
4.如果l指针l的数不等于val,则向后移动
5.最后i的值即为数组中剩余数字数目
代码:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int l = 0,r = nums.size();
while(l < r){
if(nums[l] == val){
nums[l] = nums[r-1];
r--;
}
else l++;}
return l;
}
};
方法2:快慢指针
思路:运用快慢指针,slow用来存储最终的元素个数,fast用来遍历数组的元素并和target比较,如果不同则把数据从头插入到需要返回的数组中
代码:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slow = 0;
for(int fast = 0; fast < nums.size(); fast++){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
};