二分查找——全类型整理
基础:
给定一个升序数组,找出是否存在目标数target,若存在,则返回下标,若不存在,则返回-1
(最万全的写法,int l = 0, r = nums.size(),另外,如果不熟悉,建议if写成三段式,这样最佳)
变式:
1. 找出target数的左边界,若存在,则返回下标,若不存在,则返回-1
2. 找出target数的右边界,若存在,则返回下标,若不存在,则返回-1
建议参考leetcode34题,也可部分参考:https://www.cnblogs.com/kyoner/p/11080078.html
3. 找出第一个 严格小于 target的数,若存在,则返回下标,若不存在,则返回-1
4. 找出第一个 小于等于 target的数,若存在,则返回下标,若不存在,则返回-1
(其实,3和4是伪命题,仔细想一下,只要判断第一个数字是否满足即可)
5. 找出第一个 严格大于 target的数,若存在,则返回下标,若不存在,则返回-1
6. 找出第一个 大于等于 target的数,若存在,则返回下标,若不存在,则返回-1
补充3和4题的解答:
int func(vector<int>& nums, int target) { if(nums.empty()) return -1; if(nums[0]<=target) //第4题的答案,如果是要求严格小于,则改成小于符号即可 return 0; else return -1; }
5和6题的规律(后文有完整解答):
if(target>nums[mid]) //larger or equal,6题 (如果target都严格大于nums[mid]了,那么左边区间必然不符合条件了)
{
l = mid+1;
}
else
r =mid;
// if(target>=nums[mid]) //larger than,5题
// {
// l = mid+1;
// }
// else
// r =mid;
第6题的完整解答:
// index of the first number larger or equal than target int func(vector<int>& nums, int target) { int l =0; int r = nums.size(); while(l<r) { int mid = (r-l)/2+l; if(nums[mid]==target) r = mid; //如果是严格大于,则改成 l = mid+1,用于解答第5题 else if(nums[mid]>target) r = mid; else if(nums[mid]<target) l = mid +1; } //cout<<l<<endl; if(l<nums.size()) return l; else return -1; }
第5题的解答:
// index of the first number larger than target int func(vector<int>& nums, int target) { int l =0; int r = nums.size(); while(l<r) { int mid = (r-l)/2+l; if(target>=nums[mid]) { l = mid+1; } else r =mid; } //cout<<l<<endl; if(l<nums.size()) return l; else return -1; }