1)mid 向下取整
while( left < right)
{
int mid = (right - left)/2 + left;
if( check(mid) )
{
right = mid;
}
else
{
left = mid + 1;
}
}
会把 [left, right]分成 [mid +1, right], [left, mid]两个区间。
这相当于求满足条件的最小值,
如果 [left,right]只有两个元素,则 mid == left,下一次搜索的话,left < right不满足,能退出
2)mid向上取整:
while( left < right)
{
int mid = (right - left + 1) /2 + left;
if( check(mid))
{
left = mid;
}
else
{
right = mid -1;
}
}
搜索区间[left, right]会被分割成 [left, mid-1], [mid, right]两个。
当只有两个元素的时候, mid = == right, 那么 left < right也不满足,从而能退出。这相当于求满足条件的最大值。
check函数是类似 f(mid) <= target, f(mid) >= target这样的.下面这张图可以有助于理解怎么写check函数:
例子(力扣34题):
class Solution {
public int[] searchRange(int[] nums, int t) {
int[] ans = new int[]{-1, -1};
int n = nums.length;
if (n == 0) return ans;
int l = 0, r = n - 1;
while (l < r) {
int mid = l + r >> 1;
if (nums[mid] >= t) r = mid;
else l = mid + 1;
}
if (nums[r] != t) return ans;
ans[0] = r;
l = 0; r = n - 1;
while (l < r) {
int mid = l + r + 1 >> 1;
if (nums[mid] <= t) l = mid;
else r = mid - 1;
}
ans[1] = r;
return ans;
}
}
这张图引自:
【宫水三叶】考察对「二分」的理解,以及 check 函数的「大于 小于」怎么写 - 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)
这张图引自:写对二分查找不是套模板并往里面填空,需要仔细分析题意 - 搜索插入位置 - 力扣(LeetCode)
如有侵权则删除。