二分演算法是乙個較高效率的查詢演算法,但是二分法中的細節卻經常使人感到懵圈。有一次看到一位大神整理的二分演算法細節分析,個人覺得挺好的,借鑑大神的講解,我也大致整理了一些內容。
二分演算法常用情景大致分為三種:尋找乙個數、尋找左側邊界、尋找右側邊界。
int
binarysearch
(int
nums,
int target)
else
if(nums[mid]
< target)
else
right = mid -1;
// 注意}}
return-1
;}
問題一:為什麼 while 迴圈的條件中是 <=,而不是 < ?
答:初始化 right 的賦值是 nums.length-1,即最後乙個元素的索引,而不是 nums.length。因此,搜尋區間為 [left, right],當搜尋區間縮小為 [left, left] 即(left == right),還有乙個數字 nums[left] 需要被判斷,若迴圈的終止條件為 < ,這時會遺漏乙個數字,因此,迴圈的結束條件應該是 <= 。
問題二: 為什麼 left = mid + 1,right = mid - 1?有的**是 right = mid 或者 left = mid。
答:本演算法的搜尋區間是兩端都閉的,即 [left, right]。那麼當我們發現索引 mid 不是要找的 target 時,下一步的搜尋區間當然是 [left, mid - 1] 或者 [mid + 1, right]。因為 mid 已經搜尋過,應該從搜尋區間中去除。因此,需要進行 left = mid + 1、right = mid - 1,而不是 right = mid 、left = mid。
情景二:尋找左側邊界
int
left_bound
(int
nums,
int target)
else
if(nums[mid]
< target)
else
}return left;
}
問題一:為什麼 while(left < right) 而不是 <= ?
答: right = nums.length 而不是 nums.length - 1 。因此每次迴圈的搜尋區間是[left, right) 左閉右開。while(left < right) 終止的條件是 left == right,此時搜尋區間 [left, left) 為空,所以可以正確終止。
問題二:為什麼 left = mid + 1,right = mid ?和之前的演算法不一樣?
答:因為我們的搜尋區間是 [left, right) 左閉右開,所以當 nums[mid] 被檢測之後,下一步的搜尋區間應該去掉 mid 分割成兩個區間,即 [left, mid) 或 [mid + 1, right)。
問題三:為什麼該演算法能夠搜尋左側邊界?
答:關鍵在於對於 nums[mid] == target 這種情況的處理:
if
(nums[mid]
== target)
right = mid;
問題四:為什麼沒有返回 -1 的操作?如果 nums 中不存在 target 這個值,怎麼辦?
答:當 left == nums.length 時,即 target 比所有數都大,返回 -1。否則,若nums[left] 等於 target,返回 left,否則,返回 -1.
while
(left < right)
// target 比所有數都大
if(left == nums.length)
return-1
;// 類似之前演算法的處理方式
return nums[left]
== target ? left :-1
;
注意:迴圈的終止條件是 left == right,因此,返回 left 和 right 是一樣的。
情景三:尋找右側邊界
int
right_bound
(int
nums,
int target)
else
if(nums[mid]
< target)
else
}return left -1;
// 注意
}
問題一:為什麼這個演算法能夠找到右側邊界?
答:關鍵點:
if
(nums[mid]
== target)
if(left ==0)
return-1
;return nums[left-1]
== target ?
(left-1)
:-1;
二分法查詢詳細講解
二分查詢 1 二分查詢 binary search 二分查詢又稱折半查詢,它是一種效率較高的查詢方法。二分查詢要求 線性表是有序表,即表中結點按關鍵字有序,並且要用向量作為表的儲存結構。不妨設有序表是遞增有序的。2 二分查詢的基本思想 二分查詢的基本思想是 設r low.high 是當前的查詢區間 ...
二分查詢(詳細)
先看乙個二分查詢的框架吧 else if num mid target else if num mid target return.接下來以乙個例子來理解二分查詢 include include intmain int left 0 int length sizeof num sizeof int ...
二分查詢詳細介紹
分類 演算法 search bi程式設計優化 二分查詢演算法基本思想 二分查詢演算法的前置條件是,乙個已經排序好的序列 在本篇文章中為了說明問題的方便,假設這個序列是公升序排列的 這樣在查詢所要查詢的元素時,首先與序列中間的元素進行比較,如果大於這個元素,就在當前序列的後半部分繼續查詢,如果小於這個...