無處不在的二分查詢

2021-07-25 11:32:57 字數 4895 閱讀 9604

我們都知道二分查詢演算法,實際上二分查詢以及其擴充套件應用是很廣泛的。這裡收集了一些和二分查詢有關的有趣問題。強烈建議大家看完問題後最小化瀏覽器,先嘗試自己去解決,然後再看**,問題都不是太難。

給乙個已經排序的陣列,其中有n個互不相同的元素。要求使用最小的比較次數找出其中的乙個元素。(你認為二分查詢在排序陣列裡找乙個元素是最優的演算法的嗎?)

不需要太多的理論,這是乙個典型的二分查詢演算法。先看下面的**:

01// 返回要查詢元素的下標,-1為沒有找到

02intbinarysearch(inta,intl,intr,intkey)

03

17

18return-1;

19}

理論上,我們最多需要 logn+1 次比較。仔細觀察,我們在每次迭代中使用兩次比較,除了最後比較成功的一次。實際應用上,比較也是代價高昂的操作,往往不是簡單的資料型別的比較。減少比較的次數也是優化的方向之一。

下面是乙個比較次數更少的實現:

01// 迴圈不變式: a[l] <= key &  a[r] > key

02// 邊界: |r - l| = 1

03// 輸入: a[l .... r-1]

04intbinarysearch(inta,intl,intr,intkey)

05

16if( a[l] == key )

17returnl;

18else

19return-1;

20}

在while迴圈中,我們僅依賴於一次比較。搜尋空間( l->r )不斷縮小,我們需要乙個比較跟蹤搜尋狀態。

需要注意的,要保證我們恒等式(a[l] <= key & a[r] > key)正確,後面還會用到迴圈不變式。

給乙個有n個互不相同的元素的已排序陣列,返回小於或等於給定key的最大元素。 例如輸入為 a =   key = 7,應該返回6.

分析:我們可以用上面的優化方案,還是保持乙個恒等式,然後移動 左右兩個指標。最終 left指標會指向 小於或等於給定key的最大元素(根據恒等式a[l] <= key and a[r] > key)。

- > 如果陣列中所有元素都小於key,左邊的指標left 會一直移動到最後乙個元素。

- > 如果陣列中所有元素都大於key,這是乙個錯誤條件,無答案。

- > 如果陣列中的所有元素都 <= key,這是最壞的情況根據下面的實現

**:01// 迴圈不變式: a[l] <= key and a[r] > key

02// 邊界條件: |r - l| = 1

03// 輸入: a[l .... r-1]

04// 先決條件: a[l] <= key <= a[r]

05intfloor(inta,intl,intr,intkey)

06

16returna[l];

17}

18

19// 初始呼叫

20intfloor(inta,intsize,intkey)

21

這個函式在c++的stl裡面有實現 :  lower_bound 函式

給乙個有重複元素的已排序陣列,找出給定的元素key出現的次數,時間複雜度要求為logn.

分析其實可以對上面的程式稍作修改,思路就是分別找出key 第一次出現的位置和最後一次出現的位置。

01// 輸入: 陣列區間 [l ... r)

02// 迴圈不變式: a[l] <= key and a[r] > key

03intgetrightposition(inta,intl,intr,intkey)

04

14returnl;

15}

16

17// 輸入: 陣列區間 (l ... r]

18// 恒等式: a[r] >= key and a[l] > key

19intgetleftposition(inta,intl,intr,intkey)

20

30returnr;

31}

32

33intcountoccurances(inta,intsize,intkey)

34

有乙個已排序的陣列(無相同元素)在未知的位置進行了旋轉操作,找出在新陣列中的最小元素所在的位置。

例如:原陣列 , 旋轉後的陣列可能是 ,也可能是

分析:我們不斷的縮小 l 左指標和 r 右指標直到有乙個元素。把上面劃橫線的作為第一部分,剩下的為第二部分。如果中間位置m落在第一部分,即a[m] < a[r] 不成立,我們排序掉區間 a[m+1 ... r]。 如果中間位置m落在第二部分,即 a[m]01intbinarysearchindexofminimumrotatedarray(inta,intl,intr)

02

25return-1;

26}

27

28intbinarysearchindexofminimumrotatedarray(inta,intsize)

29

無處不在的NFC

長期以來,nfc技術處於左右為難或先有雞還是先有蛋的窘境之中。在無產品支援的情況下,製造商為什麼要在手機中採用nfc,反之,當製造商在手機中採用nfc時,為什麼無產品支援?值得慶幸的是,這樣的日子已經一去不復返了,如今已有5億多部支援nfc的高階智慧型手機投入使用,此問題已得到妥善解決。nfc手機正...

無處不在的分析能力

好長時間沒寫部落格了,不是沒有時間,而是堅持的還不夠。今天遇到乙個問題,想寫出來和大家分享。昨天晚上寫到category這個頁面。主要是把類別新增到資料庫中,和從資料庫中拿出後樹狀展示。涉及的知識倒是不多,也就是判斷 迭代等。但是我從昨晚寫,知道今天中午5點才搞定。中間花費了差不多4個小時左右時間來...

無處不在的日期類

所有的類,我們已經寫到目前為止已經足夠簡單,我們已經能夠實現的功能,直接在類本身的定義。例如,我們無處不在的 日期類 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 classdate private defa...