劍指offer之面試題11 旋轉陣列的最小數字

2021-10-05 11:23:06 字數 2200 閱讀 5837

1、題目

把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個遞增排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如:陣列為的乙個旋轉,該陣列的最小值為1。

輸入引數:一維陣列numbers,陣列長度length

輸出引數:最小元素的值,或者丟擲 「傳入引數錯誤」 的異常

2、解題

解這道題的關鍵在於搞明白陣列的最小元素在旋轉陣列中的位置

旋轉陣列可以被劃分為兩個子陣列,而且前面子陣列的元素都大於等於後面子陣列的元素,最小元素的位置即為兩個子陣列的分界處,因此我們可以通過二分查詢法的思路來尋找最小元素。

具體步驟如下:

按照最小元素的位置,更新 p1 或 p2 的值,也就是縮小最小元素所在陣列的範圍

迴圈使用二分法,縮小範圍。當 p1 指向前面子陣列的末尾,p2 指向後面子陣列的開頭時,迴圈結束,此時 p2 所指即為最小元素。

以陣列為例,先將 p1 指向第0個元素,p2 指向第四個元素,下面用圖代表指標的移動過程。其中空白矩形表示前面的遞增子陣列,陰影表示後面的遞增子陣列

numbers[p1] <= numbers[pmid],指標p1後移

numbers[p2] >= numbers[pmid],指標p2前移

此時指標 p1與指標p2相鄰,最小元素找到,即為 p2所指元素

但若是就此而編寫**,則存在這樣乙個問題,當 numbers[p1] 、numbers[p2]、numbers[pmid] 這三個數相同時,按常理我們將 pmid 賦值給 p1,認為最小元素在 numbers[pmid] 的後面,可是情況卻並非如此。

以陣列為例,其旋轉陣列可以為或,如下圖所示:

此時,numbers[p1] = numbers[pmid] = numbers[p2],我們無法確定中間的數字1是屬於第乙個遞增子陣列還是第二個遞增子陣列。這時我們只能採用普通的順序查詢方法,時間複雜度變為o(n)。

3、**

int

min(

int* numbers,

int length)

//pmid指標獲得指向

pmid =

(p1 + p2)/2

;//若三個指標所指元素相等,採用順序查詢

if(numbers[p1]

== numbers[p2]

&& numbers[p1]

== numbers[pmid]

)return

mininorder

(numbers, p1, p2)

;//若pmid所指元素大於p1所指元素,p1後移,反之p2前移

if(numbers[pmid]

>= numbers[p1]

) p1 = pmid;

else

if(numbers[pmid]

<= numbers[p2]

) p2 = pmid;

}//最後返回最小元素

return numbers[pmid];}

intmininorder

(int

* numbers,

int p1,

int p2)

4、注意點

數出錯時丟擲異常而不是返回某個值

測試**見:

劍指offer面試題11

面試題1 數值的整數的次方 題目 實現函式double power double base,int exponent 求base的 exponent次方。不得使用庫函式,同時不需要考慮大數問題。思路 首先應該明確指數的可能取值 正整數,0,負整數 另外還需要考慮底數是0的情形。對於負整指數,我們可以...

劍指offer之面試題9 4 矩形覆蓋

題目描述 我們可以用2 1的小矩形橫著或者豎著去覆蓋更大的矩形。請問用n個2 1的小矩形無重疊地覆蓋乙個2 n的大矩形,總共有多少種方法?思路 用數學歸納的思想分析,得出規律。牛客網提交 public class solution if target 2 return init target int...

劍指offer之面試題11 數值的整數次方

題目描述 給定乙個double型別的浮點數base和int型別的整數exponent。求base的exponent次方。思路 這道題看似很簡單,習慣性地認為用乙個迴圈,不斷乘以base,即可 public double power double base,int exponent return re...