基本二分法
private int findFirst(int[] nums, int target) {
int low = 0;
int high = nums.length - 1; // 闭区间
while (low <= high) { // 带等号
int mid = (low + high) >>> 1;
if (nums[mid] > target) {
high = mid - 1;
} else if (nums[mid] < target) {
low = mid + 1;
} else {
// 判断左边界,变高位
return mid
}
}
return -1;
}
左边界二分法,在找到情况下,找到最左边的值
private int findFirst(int[] nums, int target) {
int low = 0;
int high = nums.length - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
if (nums[mid] > target) {
high = mid - 1;
} else if (nums[mid] < target) {
low = mid + 1;
} else {
// 判断左边界,变高位
if ((mid == 0) || (nums[mid - 1] != target)) {
return mid;
} else {
high = mid - 1;
}
}
}
return -1;
}
作者:Fancier
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/jian-dan-de-er-fen-cha-zhao-jie-fa-tong-su-yi-dong/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
右边界二分法,在找到的情况下找到最右边的值
private int findLast(int[] nums, int target) {
int low = 0;
int high = nums.length - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
if (nums[mid] > target) {
high = mid - 1;
} else if (nums[mid] < target) {
low = mid + 1;
} else {
// 判断右边界,变低位
if ((mid == nums.length - 1) || (nums[mid + 1] != target)) {
return mid;
} else {
low = mid + 1;
}
}
}
return -1;
}
作者:Fancier
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/jian-dan-de-er-fen-cha-zhao-jie-fa-tong-su-yi-dong/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
拓展:在找不到目标值的情况下,如何获得目标的上界和下界
在折半插入排序的时候,需要用二分法查到待插入的位置。用的是闭区间折半查找法,最后数据被插到了end+1位置。不过在前面判断的时候,mid值相等的时候被归到了右侧:
def bin_search(nums, target):
size = len(nums)
start = 0
end = size - 1
while start <= end:
mid = start + (end - start) // 2
if nums[mid] <= target: # 相等的时候将其排除在左侧,能保证找到右边界
start = mid + 1
else:
end = mid - 1
return [end, end + 1] # 最后end+1 位置一定是右边界