圖片、原文來自:https://www.cnblogs.com/luoxn28/p/5767571.html
以下圖片中源碼手寫板來自:https://github.com/qq249356520/AlgorithmNotes Search文件夾
上圖分別解釋了二分查找成功和失敗的兩種情況。當left > right時二分查找失敗(所給數組中沒有待查找元素)。
基本的二分查找如下:要求數組有序
常規二分查找
如果把需要查找的條件稍微變換一下,比如數組中多個重複元素,要求找到匹配的數據最小(或最大)的下標;更進一步,需要找出數組中第一個大於key的元素(也就是數組中最小的大於k的元素)下標,等等。
其變種與二分查找原理一樣,都是變換判斷條件(邊界條件)。
第一種:查找第一個與key值相等的元素的下標(常規二分查找的變種)
邊界條件改變:當arr[mid]>key加等號,改爲>=。因爲要尋找最左元素,所以需要用left判斷。
循環退出條件:left剛好指向key,right指向key的前一個元素。
第二種:查找第一個大於等於key值的元素的下標(第一種的變種)
第三種:查找第一個大於key值元素的下標(第一種與第二種的變種)
第四種:查找最後一個與key值相等的元素的下標(常規二分的變種)
邊界條件改變:當arr[mid] < key時加等號,因爲要尋找最後一個。
循環退出條件:left指向剛好大於要查找元素的元素,right指向待查找元素
第五種:查找最後一個小於等於key值元素的下標(第四種的變種)
第六種:查找最後一個小於key值元素的下標(第四種與第五種的變種)
測試用例:
總結:
我們可按照以下步驟總結二分查找變種:
1、首先判斷返回left還是返回right:
因爲結束循環的條件是left <= right,所以最後的結果必定是left = right + 1,left和right卡在邊界的兩邊
如果比較值爲k,當我們查找小於等於k的元素,則邊界值就是所有等於k的最左邊的那個,應該返回left
2、判斷比較符號:
也就是?的符號,同上,如果是查找小於等於k的元素,那麼我們應該使用 <= k 控制left 如果大於等於則 >= 控制right