浅谈二分查找
二分查找的查找问题 — 两套查找模板
1.查找是:大于等于target的最小下标 arr[mid] >= target
2.查找是:小于等于target的最大下标 arr[mid] <= target
二分查找题目有两种类型:
- 情况一:在某个数组中查找某个数字(能找到),返回下标。
- 如果target只出现一次,返回target
- 如果target出现1+次,返回:
- target首次出现的位置
- target最后出现的位置
- 情况二:在某个数组中查找某个数字(找不到)
- 直接返回-1。
- 返回它可以插入的位置,即大于target的最大下标
- 返回小于target的最大下标(特殊情况可能会使用这种方式) ---- leetcode 911 在线选举
/*
bSearch_1:用于在一个数组中找到大于等于target的最小下标
*/
int bSearch_1(vector<int> nums, int target) {
int left = 0;
int right = nums.size() - 1;
int ans = nums.size(); // 防止nums为空出现随机值
while (left <= right) {
int mid = (right - left) / 2 + left;
// mid = (l+r)>>1;
if (nums[mid] >= target) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
/*
bSearch_2:用于在一个数组中找到小于等于target的最大下标
*/
int bSearch_2(vector<int> nums, int target) {
int left = 0;
int right = nums.size() - 1;
int ans = nums.size();
while (left <= right) {
int mid = (right - left) / 2 + left;
if (nums[mid] <= target) {
ans = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
return ans;
}
测试用例
int main(void) {
vector<int> v1 = {1, 4, 5, 6, 6, 6, 8, 9};
cout << bSearch_1(v1, 3) << endl;
cout << bSearch_2(v1, 3) << endl;
return 0;
}
输出:
1
0
int main(void) {
vector<int> v1 = {1, 4, 5, 6, 6, 6, 8, 9};
cout << bSearch_1(v1, 6) << endl;
cout << bSearch_2(v1, 6) << endl;
return 0;
}
输出:
3
5