二分搜尋之搜尋陣列中目標元素的首尾下標
個人部落格:DoubleFJ の Blog
今天總結一下二分搜尋。假設這裡的陣列已經是升序排序好了的。
我們知道二分搜尋的效率很高,它充分利用了元素間的次序關係,採用分治策略,可在最壞的情況下用 O(log n) 完成搜尋任務。它的基本思想:將 n 個元素分成個數大致相同的兩半,取 a[n/2] 與需要查詢的目標值 x 作比較,如果 x=a[n/2] 則找到 x,演算法運算終止。詳情可跳轉百度百科。
- 我們通常最基本的二分搜尋是這樣實現的(Java):
/**
* 二分搜尋
*
* @param arr
* 已升序排序陣列
* @param key
* 目標查詢值
* @return
*/
public static int commonBinarySearch(int[] arr, int key) {
int low = 0;
int high = arr.length - 1;
int middle = 0; // 定義middle
if (key < arr[low] || key > arr[high] || low > high) {
return -1;
}
while (low <= high) {
middle = (low + high) / 2;
if (arr[middle] > key) {
// 比關鍵字大則關鍵字在左區域
high = middle - 1;
} else if (arr[middle] < key) {
// 比關鍵字小則關鍵字在右區域
low = middle + 1;
} else {
return middle;
}
}
return -1; // 未找到結果,返回-1
}
若是陣列中存在搜尋目標元素,則只要查詢到任意一個便會返回該值;若是沒有找到即返回 -1。
- 來看下一種,只返回目標元素第一次出現的位置下標(虛擬碼):
l = -1; u = n
while l+1 != u
m = (l + u) / 2
if x[m] < t
l = m
else
u = m
p = u
if p >= n || x[p] != t
p = -1
n 為陣列的長度,p 就是最終我們需要的下標。若是 while 迴圈出來的最終結果 u >= n
(其實最大也只會等於 n)或者 x[u] != t
(t 為我們的目標元素),那麼也就是無結果,返回 -1。
- 我們再來看最後一個 function(該方法引數不同使得結果可以返回元素第一個出現的下標或者最後一個下標,也是 Java):
/**
*
* @param nums
* 已經升序排序好的陣列
* @param target
* 搜尋目標元素
* @param left
* 是否是查詢第一個元素下標。true:查詢目標元素第一個出現下標, false:查詢目標元素最後一個出現下標
* @return
*/
private int extremeInsertionIndex(int[] nums, int target, boolean left) {
int lo = 0;
int hi = nums.length;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (nums[mid] > target || (left && target == nums[mid])) {
hi = mid;
} else {
lo = mid + 1;
}
}
return lo;
}
目標元素出現的第一個下標:int leftIdx = extremeInsertionIndex(nums, target, true);
目標元素出現的最後一個下標:int rightIdx = extremeInsertionIndex(nums, target, false) - 1;
這裡需要減一,需要注意。
總結一下:二分搜尋只需要注意它的邊界值,原先的陣列下標範圍是 [0…n-1],當你用 lo = 0, hi = n-1
去執行時,對應條件滿足情況下值的賦值應該是 lo = mid + 1, hi = mid - 1
;而若是用 lo = -1, hi = n
去作為條件執行時,對應條件滿足情況下值的賦值就應該為 lo = mid, hi = mid
,因為它兩個值都是作為邊界值。[0, n]、[-1, n-1]也是如此。
相關連結:
相關文章
- 二分搜尋樹元素的插入
- Python之 常用查詢演算法:最小項搜尋、順序搜尋、二分搜尋Python演算法
- PHP 陣列搜尋 sdk & 陣列分頁PHP陣列
- LeetCodeHot100 二分查詢 35. 搜尋插入位置 74. 搜尋二維矩陣 34. 在排序陣列中查詢元素的第一個和最後一個位置 33. 搜尋旋轉排序陣列 153. 尋找旋轉排序陣列中的最小值LeetCode矩陣排序陣列
- 從二分搜尋到二叉搜尋樹
- 織夢標籤搜尋框呼叫
- LeetCode 33——搜尋旋轉排序陣列LeetCode排序陣列
- NumPy 分割與搜尋陣列詳解陣列
- LeetCode入門指南 之 二分搜尋LeetCode
- 06 二分搜尋--ing
- 易優searchform功能:文件標題搜尋,預設搜尋整站-EyouCms手冊ORM
- LeetCode 81——搜尋旋轉排序陣列 IILeetCode排序陣列
- LeetCode33. 搜尋旋轉排序陣列LeetCode排序陣列
- LeetCode#33搜尋旋轉排序陣列LeetCode排序陣列
- LeetCode33 搜尋旋轉排序陣列LeetCode排序陣列
- 【LeetCode(Java) - 33】搜尋旋轉排序陣列LeetCodeJava排序陣列
- leetCode33搜尋旋轉排序陣列LeetCode排序陣列
- 二分搜尋樹系列之[ 插入操作 (insert) ]
- 二分搜尋樹系列之「 插入操作 (insert) 」
- 二分搜尋(折半查詢)
- 【Java】尋找陣列中“主要元素”Java陣列
- 二分搜尋演算法求元素位置(c語言)演算法C語言
- js 從目標陣列中過濾掉 一個陣列元素,JS陣列
- 直播系統程式碼,常用搜尋中搜尋歷史,搜尋推薦功能
- 最佳路徑搜尋(二):啟發式搜尋(代價一致搜尋(Dijkstra search),貪心搜尋,A*搜尋)
- 海量資料搜尋---搜尋引擎
- 力扣·33. 搜尋旋轉排序陣列力扣排序陣列
- leetcode, LC68:旋轉排序陣列搜尋LeetCode排序陣列
- js之搜尋框JS
- elasticsearch之拼音搜尋Elasticsearch
- 資料結構之PHP二分搜尋樹資料結構PHP
- 基於布穀鳥搜尋的多目標最佳化matlab模擬Matlab
- 240. 搜尋二維矩陣 II 和74. 搜尋二維矩陣矩陣
- 尋找陣列中第K大的元素陣列
- 二分搜尋樹(Binary Search Tree)
- 搜尋
- 陣列的查詢(搜尋):線性查詢和二分法查詢陣列
- 搜尋引擎-03-搜尋引擎原理