標準二分查找的模板:
class BinarySearch {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target) return mid;
else if (nums[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
}
循環條件: left <= right
中間位置計算: mid = left + ((right -left) >> 1)
左邊界更新:left = mid + 1
右邊界更新: right = mid - 1
返回值: mid / -1
這里有幾點需要注意:
我們的循環條件中包含了
1、left == right的情況,則我們必須在每次循環中改變 left 和 right的指向,以防止進入死循環
2、循環終止的條件包括:
(1)找到了目標值
(2)left > right (這種情況發生于當left, mid, right指向同一個數時,這個數還不是目標值,則整個查找結束。)
3、left + ((right -left) >> 1) 其實和 (left + right) / 2是等價的,這樣寫的目的一個是為了防止 (left + right)出現溢出,一個是用右移操作替代除法提升性能。
4、left + ((right -left) >> 1) 對于目標區域長度為奇數而言,是處于正中間的,對于長度為偶數而言,是中間偏左的。因此左右邊界相遇時,只會是以下兩種情況:
(1)left/mid , right (left, mid 指向同一個數,right指向它的下一個數)
(2)left/mid/right (left, mid, right 指向同一個數)
即因為mid對于長度為偶數的區間總是偏左的,所以當區間長度小于等于2時,mid 總是和 left在同一側。