二分查詢Binary Search

2021-07-27 03:38:34 字數 1726 閱讀 7619

二分查詢,屬於分治思想大類。基本思想是每次將所需要處理的資料空間進行減少(一般減少一半),以達到快速減少所需處理空間,減少執行時間的效果。時間複雜度一般以o(logn)為標識。

基本模板

1

public

int binarysearch (int nums, int target)

2int low = 0, hight = nums.length-1, mid =0;

3while ( low < hight)

6else

if (nums[mid] > nums[low])

8else

11 return low;

二分查詢的典型應用場景,需要滿足兩個條件:

1.資料有序

2. 資料儲存在陣列中:為了便於每次的mid計算

因此,如果直接資料不滿足上面條件,也可以通過適當的轉換,使之滿足標準。

二分查詢的基本「套路」,無非是先確定low和high,然後計算low和hight的中間位置mid,通過比較位於中間的值來決定以什麼樣的方式縮小。接下來對每個步驟進行詳細說明。

1.low和high的確定

【模板**第1行】

一般來說,對於普通的陣列或是普遍的演算法題目中,low取為0(資料開始位置),high取為整個資料的長度。但是也不全是。對於low和high的選取,也是二分查詢的難點。一般正確的頭尾選取,標誌了正確解題思路的開始。這裡舉幾個選取lo-hi的不同例子。

eg:輸入乙個矩陣(2維陣列),求乙個target,問這個值是否存在矩陣中。矩陣的特點是每行從左往右遞增,每列從上到下遞減。

solution:從左上角開始查詢。當當前值比target大,則遞減列,當比target小,則遞增行。

另外,2d矩陣中,有的題目是low是左上角元素,high是右下角元素。因此low和high的選擇還是很重要的。

2.確定mid的比較

【模板**第4,6行】

mid的比較,換句話說如何將當前的mid的值和low和high進行比較。一般常用的是如模板**4,6行的模式。這裡的mid和lo-hi的比較,是直接比較大小。但是有時候,對於如何進行mid的比較,是比較有技巧的,也是屬於解題的關鍵步驟。一般來講,第一步low和high確定了,基本mid也知道了如何比較。

3.確定邊界條件

【模板**第3,5,7,9行】

邊界條件的確定,各種細節會在很多時候會讓大家感覺思路沒有問題,但是總是無法ac。主要原因就是各種邊界條件、是《還是<=等問題。這裡進行總結一下。

3.1. while(low < high) or while(low<=high)?

這是二分法遇到的第乙個需要判斷需不需要等於的地方。判斷條件很簡單:假設當輸入陣列中只有乙個或只剩乙個元素的時候,是否還需要進行mid判斷。如果需要,則是<=。反之,只剩乙個元素時不需要判斷,則不用=。

3.2. low = mid+1 ? low = mid? high = mid-1? high = mid?

這裡的判斷同樣需要根據題意。首先依據while的情況,簡單確定一下。

tips: mid = low+(high - low)>>1

在計算mid的時候,如果直接mid = (low + high)/2,可能會導致溢位。移位操作會加快速度。

STL中的二分查詢(binary search)

stl中對於有序序列 vector,list等 提供了相當相當強大的二分搜尋binary search演算法。對於可以隨機訪問容器 如vector等 binary search負載度為對數級別 logn 對於非隨機訪問容器 如list 則演算法複雜度為線性。現在簡要介紹一下幾種常用的binary s...

迭代二分查詢二分查詢

在寫這篇文章之前,已經寫過了幾篇關於改迭代二分查詢主題的文章,想要了解的朋友可以去翻一下之前的文章 bentley在他的著作 writing correct programs 中寫道,90 的計算機專家不能在2小時內寫出完整確正的二分搜尋演算法。難怪有人說,二分查詢道理單簡,甚至小學生都能明確。不過...

1128 二分 二分查詢

時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述nettle最近在玩 艦 因此nettle收集了很多很多的船 這裡我們假設nettle氪了很多金,開了無數個船位 去除掉重複的船之後,還剩下n 1 n 1,000,000 種不同的船。每一艘船有乙個稀有值,任意兩艘船的稀有...