1.704二分查找
二分查找中首先需要明确的就是更新遍历的区间即循环不变量第一种是[left,right]的搜索空间,第二种是[left,right)的搜索空间。
循环不变量:在每次循环的时候,其对应的逻辑都不会改变。
对于第一种的时候,如果target小于nums[mid],那么此时的nums[mid]一定搜索空间内,所以更新的时候right = mid - 1;同理对于大于的情况也是mid不在搜索空间内,left = mid+1;
对于第二种情况,由于是左闭右开的空间,此时我们在进行更新的时候,需要确保搜索空间有效,即left<right,此时是不能取等于的,因为[left,left)是无效的数组空间,还有就是后面的大于的时候,此时right = mid,因为此时的搜索空间是[)。
class Solution {
public:
int search(vector<int>& nums, int target) {
int n = nums.size();
/*
//构建一个数组[left,right];第一种写法是左闭右闭,需要注意里面对应的一个循环不变量
int left = 0,right = n-1;
while(left<=right){//代表这个数组是有效的
int mid =left+(right-left)/2;
if(nums[mid] == target){
return mid;
}else if(nums[mid]<target){
left = mid+1;
}else{
right = mid-1;
}
}*/
//第二种写法,按照左闭右开的方法进行写
int left = 0,right = n;
while(left<right){
int mid = left+(right-left)/2;
if(nums[mid]==target){
return mid;
}else if(nums[mid]<target){
left = mid+1;
}else{
right = mid;
}
}
return -1;
}
};
2.27移除元素
移除元素,按照题目给定的是需要进行值的覆盖,这很适合双指针中的快慢指针。
双指针:就是用两个指针来代替双重循环,减少遍历次数。
快慢指针:是双指针的一种表现形式,还有其他的比如左右指针,一个指向left,一个指向right,快慢指针,比较常用的第一种是fast指针用于遍历,slow用于数组的更新。第二种是fast一次走两步,slow一次走一步,比较典型的应该是寻找循环链表的节点位置。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n = nums.size();
int slow = 0,fast = 0;
//双指针:快慢指针,fast用于遍历,slow用于赋值更新得到返回数组
while(fast<n){
if(nums[fast]!=val){
nums[slow++] = nums[fast];
}
fast++;
}
return slow;
}
};