基本二分法
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 位置一定是右邊界