1. 題目
把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如,數組{3, 4, 5, 1, 2}爲{1, 2, 3, 4, 5}的一個旋轉,該數組的最小值爲1。
2. 解題思路
2.1 思路1
不使用條件“遞增排序”,直接遍歷數組,獲取最小值。
2.2 思路2
不使用條件“遞增排序”,直接遍歷數組,當arr[i] > arr[i+1]時,表明arr[i+1]是該數組的最小值。
2.3 思路3
使用條件“遞增排序”,使用二分查找。
3. 代碼實現
3.1 思路1的代碼實現
時間複雜度O(n),空間複雜度S(1)
class Solution:
def minArray(self, numbers):
"""
"""
if not numbers:
return
min_value = numbers[0]
for i in numbers:
if i < min_value:
return i
return min_value
3.2 思路2的代碼實現
時間複雜度O(n),空間複雜度S(1)
class Solution:
def minArray(self, numbers):
"""
"""
if not numbers:
return
for i in range(len(numbers)-1):
if numbers[i] > numbers[i+1]:
return numbers[i+1]
return numbers[0]
3.3 思路3的代碼實現
來源 leetcode 面試題11. 旋轉數組的最小數字(二分法,清晰圖解)
時間複雜度O(log2 n),空間複雜度S(1)
class Solution:
def minArray(self, numbers: [int]) -> int:
i, j = 0, len(numbers) - 1
while i < j:
m = (i + j) // 2
if numbers[m] > numbers[j]: i = m + 1 # m處的值大於j處的值,表明最小值在m的右邊
elif numbers[m] < numbers[j]: j = m # m處的值小於j處的值,表明最小值在m的左邊
else: j -= 1 # m處的值等於j處的值時,無法判斷 m 在哪個排序數組中,j = j - 1縮小範圍。
return numbers[i]
4. 總結
很明顯,前兩種解法並沒有充分利用題目中的已知條件,所以在解題是要利用所有條件來思考。
5. 參考文獻
[1] 劍指offer叢書