減而治之 - 二分查找 - lower_bound實現原理
阿新 • • 發佈:2019-03-22
算法 lse splay col while pan 有序 實現 利用
本文介紹利用二分實現 lower_bound 的原理。
lower_bound(T * a, T & t, int lo, int hi) 的功能是:在某個有序數組 a[lo, hi) 的範圍內,查找不小於 t 的最小元素或最小元素位置。這可以用二分來實現。
算法可以這樣理解。我們維護兩個界限,分別為:
L:保證 ≤ L 位置的元素都小於 t;
R:保證 ≥ R 位置的元素都大於等於 t。
我們不斷改變 L 和 R 的位置,使 L 和 R 不斷靠近,直至 L + 1 = R 時,R 即為我們要查找的目標位置。
假想 lo-1 位置存放著一個 -∞ 的哨兵,hi 位置存放著一個 +∞ 的哨兵。初始時 L = lo - 1, R = hi。
如何調整 L 和 R 的位置呢?每次觀察區間 [L, R] 中間位置的元素,即 A[mid = (L+R)/2] 的元素與 t 的大小,因為 A 的有序性:
若 A[mid] ≥ t, 我們可以把 R 替換為 mid。
若 A[mid] < t,我們可以把 L 替換為 mid。
這樣,L 和 R 不斷靠近,直至 L + 1 == R,則結束,R 則為我們要找的目標位置。
C++代碼示例(設要查找的類型是整數):
/* 返回按升序排列的 a[lo, hi) 中不小於 t 的最小值的下標。若不存在,則返回hi */ int lowerBound(int * a, int t, int lo, int hi) { int L = lo - 1, R = hi; while ( L + 1 < R ) { int mid = (L + R) >> 1; if ( a[mid] < t ) L = mid;else R = mid; } return R; }
減而治之 - 二分查找 - lower_bound實現原理