二分查找2
二分查找法作為一種常見的查找方法,將原本是線性時間提升到了對數(shù)時間范圍,大大縮短了搜索時間,但它有一個前提,就是必須在有序數(shù)據(jù)中進行查找。
二分查找很好寫,卻很難寫對,據(jù)統(tǒng)計只有10%的程序員可以寫出沒有bug的的二分查找代碼。出錯原因主要集中在判定條件和邊界值的選擇上,很容易就會導(dǎo)致越界或者死循環(huán)的情況。
下面對二分查找及其變形進行總結(jié):
1. 最基本的二分查找
public int binarySearch(int[] A, int target, int n){int low = 0, high = n, mid;while(low <= high){mid = low + (high - low) / 2;if(A[mid] == target){return mid;}else if(A[mid] > target){high = mid - 1;}else{low = mid + 1;}}return -1; }其中,有幾個要注意的點:
leetcode參考:Search Insert Position
2. 查找目標值區(qū)域的左邊界/查找與目標值相等的第一個位置/查找第一個不小于目標值數(shù)的位置
A = [1,3,3,5, 7 ,7,7,7,8,14,14]
target = 7
return 4
3. 查找目標值區(qū)域的右邊界/查找與目標值相等的最后一個位置/查找最后一個不大于目標值數(shù)的位置
A = [1,3,3,5,7,7,7, 7 ,8,14,14]
target = 7
return 7
此題以可變形為查找第一個大于目標值的數(shù)/查找比目標值大但是最接近目標值的數(shù),我們已經(jīng)找到了最后一個不大于目標值的數(shù),那么再往后進一位,返回high + 1,就是第一個大于目標值的數(shù)。
劍指offer:數(shù)字在排序數(shù)組中出現(xiàn)的次數(shù)
4. 查找最后一個小于目標值的數(shù)/查找比目標值小但是最接近目標值的數(shù)
此題以可由第 2 題變形而來,我們已經(jīng)找到了目標值區(qū)域的下(左)邊界,那么再往左退一位,即low - 1,就是最后一個小于目標值的數(shù)。其實low - 1也是退出循環(huán)后high的值,因為此時 high剛好等于low - 1,它小于low,所以 while 循環(huán)結(jié)束。我們只要判斷high是否超出邊界即可。
A = [1,3,3, 5 ,7,7,7,7,8,14,14]
target = 7
return 3
5. 查找第一個大于目標值的數(shù)/查找比目標值大但是最接近目標值的數(shù)
此題以可由第 3 題變形而來,我們已經(jīng)找到了目標值區(qū)域的上(右)邊界,那么再往右進一位,即high + 1,就是第一個大于目標值的數(shù)。其實high + 1也是退出循環(huán)后low的值,因為此時 low剛好等于high + 1,它大于high,所以 while 循環(huán)結(jié)束。我們只要判斷l(xiāng)ow是否超出邊界即可。
A = [1,3,3,5,7,7,7,7, 8 ,14,14]
target = 7
return 8
?
總結(jié)
- 上一篇: 数据库:数据库死机和掉电时如何让恢复数据
- 下一篇: JVM:锁机制