二分查找一般步骤
1、循环继续的条件while(l<r)
2、写if和else思考num[mid]满足什么性质而不是目标元素,再判断mid左(右)边有没有目标元素
3、int mid=l+(r-l)/2
注:默认向下取整,永远取不到右边界,在面对l=mid和r=mid-1这种边界收缩行为就容易出现死循环
4、退出循环后看要对num[l]是否为目标元素再做检查
总结
1、找mid,把区间分成了[l,mid-1]和[mid,r]两部分,这里除非l==r(事实上因为while的条件是left<right,所以这种情况不会发生),mid的取值永远是在l的右边。
int mid = left + ((right - left + 1)>>1);
2、判断是在mid和r是否在旋转点的同一侧
int search(vector<int>& nums, int target) {
int n=nums.size();
if(n==0) return -1;
int l=0,r=n-1;
while(l<r){
int mid=l+((r-l+1)>>1);
//当满足下面情况时,mid和r均在旋转点的同一侧,或者他们直接就都位于旋转点上面
if(nums[mid]<=nums[r]){
//满足下面情况,表示目标点在[mid,r]的范围内
if(target>=nums[mid]&&target<=nums[r]) l=mid;
else r=mid-1;
}
//mid和r是否在旋转点的异侧
else{
//满足下面情况,表示目标点在[l,mid)的范围内
if(target<nums[mid]&&target>=nums[l]) r=mid-1;
else l=mid;
}
}
return (nums[l]==target)?l:-1;
}