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...