- 我写二分老是死循环,找了个模板:点击链接
左闭右闭 : [left, right]
- 基础模板1
- while条件 left <= right 时:
- left = mid + 1
- right = mid - 1
- 基础模板2
- while条件 left < right 时:
- mid = (left + right) / 2
- left = mid + 1
- rgiht = mid
NOTE
这里 (left - 1)但是right没有减一 的理解:
本轮已经判断完mid了,实际上就应该判断[left, mid - 1] (或者[mid + 1, right])
(就像基础模板1一样)
然而, 对于left + 1 = right 时, mid = (left + right) / 2 = left 是取不到(mid - 1)这个位置的,
所以让right = mid, 而不是 (mid - 1), 让他能够取的到 (mid - 1).
查找数组中是否有target
int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.size() - 1;
int mid;
while (left <= right) {
// 选择中位数时下取整
mid = (left + right) / 2;
// check(mid)
if(target > nums[mid]) {
// 下一轮搜索区间是 [mid + 1, right]
left = mid + 1;
} else if(target < nums[mid]) {
// 下一轮搜索区间是 [left, mid - 1]
right = mid - 1;
} else {
// 找到了mid
break;
}
}
return nums[mid] == target ? mid : -1;
}
第一个大于等于target的下标
// 找到第一个 >=target 的位置
int binarySearch1(vector<int> nums, int target) {
int l = 0, r = nums.size() - 1;
// 如果 target > 数组中所有元素, 则返回nums.size()
if (target > nums[r])
return nums.size();
while (l < r) {
// mid向下取整
int mid = (l + r) / 2;
if (nums[mid] < target) {
// 说明target在 [mid + 1, r]
l = mid + 1;
} else {
// 说明target在 [l, mid]
r = mid;
}
}
cout << "target=" << target << " l=" << l << endl;
// 跳出循环时l=r, 为数组中第一个大于等于target的元素
return l;
}