建议使用V2
https://www.bilibili.com/video/BV1AP41137w7/?spm_id_from=333.788&vd_source=88184dae257eecf4353eecdafc614dd4
// nums 非递减的,即nums[i] <= nums[i+1]
// 返回最小的满足 nums[i] >= target 的 i
// 如不存在,返回len(nums)
// nums[i] > x的最小i -> (>= x+1 最小i)
// nums[i] < x的最大i -> (>= x 最小i)左边的数
// nums[i] <= x的最大i -> (> x 最小i)左边的数 -> (>= x+1最小i)左边的数
private int lowerBoundV1(int[] nums, int target) {
int lo = 0;
int hi = nums.length-1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
if (nums[mid] < target) { // 红色;[L, M]都是红色;
lo = mid + 1; // L-1始终是红色
} else { // 蓝色;[M,R]都是蓝色;
hi = mid - 1; // R+1始终是蓝色
}
}
return hi+1; // lo
}
private int lowerBoundV2(int[] nums, int target) {
int lo = 0;
int hi = nums.length;
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
if (nums[mid] < target) { // < target 红色;[L, M]都是红色;
lo = mid + 1;
} else { // >= target 蓝色;[M,R)都是蓝色;
hi = mid;
}
}
return hi; // lo
}
private int lowerBoundV3(int[] nums, int target) {
int lo = -1;
int hi = nums.length;
while (lo+1 < hi) {
int mid = lo + (hi - lo) / 2;
if (nums[mid] < target) { // < target 红色;(L, M]都是红色;
lo = mid;
} else { // >= target 蓝色;[M,R)都是蓝色;
hi = mid;
}
}
return hi;
}
leetcode
-
- 寻找旋转排序数组中的最小值
-
- 寻找旋转排序数组中的最小值 II
-
- 搜索旋转排序数组
-
- 搜索旋转排序数组 II
-
- 在排序数组中查找元素的第一个和最后一个位置
-
- 寻找峰值
-
- 山脉数组的峰顶索引
红蓝染色 [lo, hi)
- mid所处位置,mid在target左侧 是在红色,mid在target位置,或者是右侧,则是蓝色。
- 如果是红色,则 [lo, mid] 都是红色,如果是蓝色,则[mid, hi) 都是蓝色。