1 題目描述
把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如,數組 [3,4,5,1,2] 爲 [1,2,3,4,5] 的一個旋轉,該數組的最小值爲1。
示例 1:
輸入:[3,4,5,1,2]
輸出:1
示例 2:
輸入:[2,2,2,0,1]
輸出:0
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
2 解題思路
參考大佬的題解,寫的超級有條理還特別好理解:面試題11. 旋轉數組的最小數字(二分法,清晰圖解)
- 解題方法: 二分法
如下圖所示,尋找旋轉數組的最小元素即爲尋找 右排序數組 的首個元素 numbers[x] ,稱x 爲 旋轉點 。
排序數組的查找問題首先考慮使用 二分法 解決,其可將遍歷法的線性級別 時間複雜度降低至 對數級別
。
作者:jyd
鏈接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/solution/mian-shi-ti-11-xuan-zhuan-shu-zu-de-zui-xiao-shu-3/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
3 解決代碼
- 解題方法: 二分法《Java代碼》
class Solution {
public int minArray(int[] numbers) {
int i = 0;
int j = numbers.length - 1;
while(i < j){
int m = (i + j) /2;
//當 numbers[m] > numbers[j]時: m 一定在 左排序數組 中,
//即旋轉點 x 一定在 [m+1,j] 閉區間內,因此執行 i=m+1;
if(numbers[m] > numbers[j]){
i = m + 1;
}
//當 numbers[m] < numbers[j]時: m 一定在 左排序數組 中,
//即旋轉點 x 一定在 [i,m] 閉區間內,因此執行 j = m;
else if(numbers[m] < numbers[j]){
j = m;
}
//當 numbers[m] == numbers[j] 時: 無法判斷 m 在哪個排序數組中,
//即無法判斷旋轉點 x 在 [i,m] 還是 [m+1,j] 區間中。解決方案: 執行 j=j−1 縮小判斷範圍
else{
j= j - 1;
}
}
//當 i=j 時跳出二分循環,並返回 numbers[i] 即可。
return numbers[i];
}
}
- 解題方法: 二分法《python3代碼》
class Solution:
def minArray(self, numbers: List[int]) -> int:
i = 0
j = len(numbers )- 1
while i < j:
m = (i + j) //2
if numbers[m] > numbers[j]:
i = m + 1
elif numbers[m] < numbers[j]:
j = m
else:
j = j - 1
return numbers[i]