前言
在做LIS的O(nlgn)算法時,用到了二分查找算法。對於其中的一些條件,例如 l<r 和 l <= r 的區別,r = mid和r = mid-1的區別等等不是很瞭解,於是進行了一些學習。
找第一次的出現位置
二分查找因爲有幾個限制,其中一個便是 單調序列 這個要求,所以可能出現 2 3 4 4 4 5 6這樣的數組,那麼返回第一個出現的位置便是 i = 3時。
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
a[i] | 2 | 3 | 4 | 4 | 4 | 5 | 6 |
- 具體思路 :對於 l = 0,r = 6的區間,每次求mid = l+(r-l)/2 (這裏是因爲怕溢出,如果是l+r,可能溢出你設置的類型,比如溢出int),判斷a[mid]與所查找的數x的大小關係,如果 a[mid] < x,那麼l = mid+1。否則 r = mid。這裏因爲 /2 都是向下取整,所以r = mid ,r右移。
例如 尋找 4 第一次出現的位置,最後 r = 2,mid = 1,a[mid] < x,l右移,則確定 第一個4. - 代碼 :
while (left < right) {
mid = left + (right - left) / 2;
if (arr[mid] < target) left = mid + 1;
else right = mid;
}
if (arr[left] == target) return left;
else return -1;
找最後一次出現的位置
例子和上面的一樣
-
具體思路 :因爲要讓l 右移,所以每次 mid = l + (r-l+1)/2,代表向上取整,每次判斷 a[mid]與x,如果a[mid] > x,r = mid -1。否則 l = mid。這樣就能保證返回最後一次出現的位置。
-
代碼:
while (left < right) {
mid = left + (right - left + 1) / 2;
if (arr[mid] > t) right = mid - 1;
else left = mid;
}
if (arr[left] == target) return left;
else return -1;