二分查詢總結
技術標籤:刷題
1. 二分查詢:如果找到key,結束迴圈
如果找到key,結束迴圈。返回mid。
如果找不到key,最終的結束狀態會是right < left,並且right + 1 = left。返回-1。
public static int binarySearch(int[] nums,int target,int left, int right) {
//迴圈條件
while (left <= right) {
//計算mid
int mid = left + ((right - left) >> 1);
if (nums[mid] == target) {
return mid;
}else if (target > nums[mid]) {
//target在右邊
left = mid + 1;
} else {
//target在左邊
right = mid - 1;
}
}
//邊界情況:沒有找到該元素,返回 -1
return -1;
}
變種:找到key並不結束迴圈,最終總是因為right < left結束迴圈
當陣列中不存在key時或找到key並不結束迴圈,最終的結束狀態會是right < left,並且right + 1 = left。
當陣列中存在key時,根據二分割槽間選擇的不同,這裡又分為兩種情況:
1. 比較符號和返回值的變化:
左邊情況:target <= nums[mid] 即:等於情況合併到target < nums[mid] right = mid - 1
1)用於找target下邊界(第一個target)或第一個大於等於target的值:return left;
右邊情況:target >= nums[mid] 即:等於情況合併到target > nums[mid] left = mid + 1
1)用於找target上邊界(最後一個target)即最後一個小於等於target的值:return right;
2)第一個大於target的值:return left;
主體只要分情況更改 target ?= nums[mid] 和return left/right即可。
2. 邊界情況的判斷:
有時題意會有找不到的邊界情況,此時返回-1,要注意邊界情況的判斷:
1)查詢target的上下邊界,如不存在返回[-1, -1]
int upper = upperBound(nums,target); //return right
int low = lowerBound(nums,target); //return left
//邊界條件:不存在的情況
if (upper < low) {
return new int[]{-1,-1};
}
return new int[]{low,upper};
2)查詢第一個與target相等的元素,如不存在返回-1
//arr[right] < key <= arr[left]
//right是最後一個小於key的
//left是第一個大於等於key的
if (left < nums.length && nums[left] == target) {
return left;
}
return -1;
3)查詢最後一個與target相等的元素,如不存在返回-1
//arr[right] <= key < arr[left]
//right是最後一個小於等於key的
//left是第一個大於key的
if (right >= 0 && nums[right] == target) {
return right;
}
return -1;
3. 總結
public static int binarySearch(int[] nums,int target,int left, int right) {
//迴圈條件
while (left <= right) {
//計算mid
int mid = left + ((right - left) >> 1);
}else if (target ? nums[mid]) { //#### 1
//target在右邊
left = mid + 1;
} else {
//target在左邊
right = mid - 1;
}
}
//####2: 在查詢第一個或最後一個與target相等的元素時,要加上if判斷
return ?; //####3: return left or right
//沒有找到該元素
return -1;
}
比較符號:左邊情況 <=,右邊情況 <
返回值:左邊情況 right,右邊情況 left
邊界情況:return -1
reference:
https://www.cnblogs.com/gongpixin/p/6761389.html