Android 面試常見 - 二分查詢演算法題

yilian發表於2019-11-13



Android 面試常見 - 二分查詢演算法題前言

“剁手”雙十一,老闆不給漲工資怎麼辦?那就只有跳槽漲工資了。

在面試的過程中,有時候難免會碰到一些演算法題目。今天,為大家整理了二分查詢常見的演算法題。

主要包括以下三點

  1. 旋轉陣列中的最小數字
  2. 在旋轉陣列中查詢某個數
  3. 排序陣列中某個數的出現次數

旋轉陣列的最小數字

題目:把一個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。

輸入一個遞增排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。例如陣列{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉,該陣列的最小值為1.

實現陣列的旋轉見左旋轉字串。

解題思路

和二分查詢法一樣,用兩個指標分別指向陣列的第一個元素和最後一個元素。

我們注意到旋轉之後的陣列實際上可以劃分為兩個排序的子陣列,而且前面的子陣列的元素都大於或者等於後面子陣列的元素。

我們還可以注意到最小的元素剛好是這兩個子陣列的分界線。我們試著用二元查詢法的思路在尋找這個最小的元素。

首先我們用兩個指標,分別指向陣列的第一個元素和最後一個元素。按照題目旋轉的規則,第一個元素應該是大於或者等於最後一個元素的(這其實不完全對,還有特例。後面再討論特例)。 Android 面試常見 - 二分查詢演算法題



接著我們得到處在陣列中間的元素。如果該中間元素位於前面的遞增子陣列,那麼它應該大於或者等於第一個指標指向的元素。

此時陣列中最小的元素應該位於該中間 元素的後面。我們可以把第一指標指向該中間元素,這樣可以縮小尋找的範圍。

同樣,如果中間元素位於後面的遞增子陣列,那麼它應該小於或者等於第二個指標指 向的元素。

此時該陣列中最小的元素應該位於該中間元素的前面。我們可以把第二個指標指向該中間元素,這樣同樣可以縮小尋找的範圍。我們接著再用更新之後的 兩個指標,去得到和比較新的中間元素,迴圈下去。


Android 面試常見 - 二分查詢演算法題

按照上述的思路,我們的第一個指標總是指向前面遞增陣列的元素,而第二個指標總是指向後面遞增陣列的元素。

最後第一個指標將指向前面子陣列的最後一個元素, 而第二個指標會指向後面子陣列的第一個元素。也就是它們最終會指向兩個相鄰的元素,而第二個指標指向的剛好是最小的元素。這就是迴圈結束的條件。

核心實現程式碼:

Android 面試常見 - 二分查詢演算法題



注意:當兩個指標指向的數字及他們中間的數字三者相同的時候,我們無法判斷中間的數字是位於前面的字陣列還是後面的子陣列中,也就無法移動兩個指標來縮小查詢的範圍。此時,我們不得不採用順序查詢的方法。

2 旋轉陣列中查詢某個數字

要求:一個沒有重複元素的旋轉陣列(它對應的原陣列是有序的),求給定元素在旋轉陣列內的下標(不存在的返回-1)。

例如

有序陣列為{0,1,2,4,5,6,7},它的一個旋轉陣列為{4,5,6,7,0,1,2}。

元素6在旋轉陣列內,返回2
元素3不在旋轉陣列內,返回-1

分析

遍歷一遍,可以輕鬆搞定,時間複雜度為O(n),因為是有序陣列旋轉得到,這樣做肯定不是最優解。有序,本能反映用二分查詢,舉個例子看看特點
可以看出中間位置兩段起碼有一個是有序的(不是左邊,就是右邊),那麼就可以在有序的範圍內使用二分查詢;如果不再有序範圍內,就到另一半去找。

參考程式碼

Android 面試常見 - 二分查詢演算法題



擴充套件

邊的有求是沒有重複的元素,現在稍微擴充套件下,可以有重複的元素,其他的要求不變。

思路:大致思路與原來相同,這是需要比較A[beg] 與 A[mid]的關係

Android 面試常見 - 二分查詢演算法題



3 數字在排序陣列中的出現次數

Android 面試常見 - 二分查詢演算法題

Android 面試常見 - 二分查詢演算法題
看完這些感覺怎麼樣,想要面試的程式設計師,可以多看看演算法,直通bat的問題和原始碼可以學習一下


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69952849/viewspace-2663874/,如需轉載,請註明出處,否則將追究法律責任。

相關文章