把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。
輸入乙個遞增排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。
例如,陣列 [3,4,5,1,2] 為 [1,2,3,4,5] 的乙個旋轉,該陣列的最小值為1。
輸入:[3,4,5,1,2]
輸出:1
輸入:[2,2,2,0,1]
輸出:0
此題很容易想到順序查詢,時間複雜度為 o(n),但顯然順序查詢沒有利用到旋陣列的特點,必然還有更優解。
有序序列查詢問題很容易想到二分法,此題也可以用二分法。但此題並不是嚴格意義上的有序序列,而是兩個遞增序列的拼接,且第二個遞增序列的所有數一定小於等於第乙個遞增序列的最小值。
此題的二分思路:
準備兩個指標:first、second。一開始 first 指向序列首元素,second 指向尾元素。
計算 mid,比較它們所指向的元素的大小。
如果 first = mid = second,由於此序列不是嚴格有序,因此無法獲悉下一步指標該如何移動,二分法失效。
如果 mid > first,代表 mid 指向的是第乙個遞增序列,first 移動到 mid 位置。
反之,代表 mid 指向的是第二個遞增序列,second 移動到 mid 位置。
移動過程中 first 永遠指向第乙個遞增序列,second 永遠指向第二遞增序列。
當 first 和 second 的距離為1時,代表 second 指向的是第二個遞增序列的首元素,即整個序列的最小值。
如果題目追加序列沒有重複元素的條件,則二分法將不可能失效。二分法失效會重新採用順序查詢,複雜度降為 o(n),而現在複雜度可以保證為 o(logn)。
class
solution
// 如果 first 和 second 的距離是1,代表此時 second 指向的是第二個遞增數列的第乙個元素,即最小數
while
(second - first >1)
else
if(numbers[mid]
>= numbers[first]
)else
}return numbers[second];}
private
intfindmin
(int
numbers)
return num1;
}}
11 旋轉陣列的最小數字
把乙個陣列最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個非遞減排序的陣列的乙個旋轉,輸出旋轉陣列的最小元素。例如陣列為的乙個旋轉,該陣列的最小值為1。我的 二分法 class min defsolution self,nums a nums 0 b nums 1 iflen num...
11 旋轉陣列的最小數字
二分法搜尋方法 include using namespace std intmin int numbers,int length int index1 0 int index2 length 1 int indexmid index1 while numbers index1 numbers in...
11 旋轉陣列的最小數字
class solution1 int res array 0 遍歷陣列,找出最小值 for int i 1 i array.length i return res class solution2 if nums.length 1 nums nums.length 1 nums 0 int p1 0...