把一個數組最開始的若干個元素搬到數組的末尾,我們稱之爲數組的旋轉。輸入一個遞增排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如,數組 [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
注意:本題與主站 154 題相同:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
思路1:暴力(一遍掃描)
本來想者接用二分的思想來做,對二分的條件進行了改進,最後發現還是不行,只能針對沒有重複數字的情況,於是改用暴力。
class Solution:
def minArray(self, numbers: List[int]) -> int:
min_num = numbers[0]
for i in range(1, len(numbers)):
if min_num > numbers[i]:
min_num = numbers[i]
break
return min_num
思路2:二分
上面還說了二分不行,看了題解發現可以解決上面遇到的障礙。
l: 區間左邊
r: 區間右邊
m:區間中點
可能遇到的情況:
1、左邊區間遞增,則不包括最小值,此時應該: l = m + 1
2、左邊區間下降,則包括最小值,此時應該:r = m
3、右邊區間遞增,則不包括最小值,此時應該:r = m
4、右邊區間下降,則包括最小值,此時應該:l = m + 1
5、以上條件都不滿足,則表示 l,r,m對應的值都相等,無法確定最小值在哪,但是既然相等,那麼我們可以縮小區間,刪除r或者l對應的值,不會導致最小值丟失的,故此時可以:r = r - 1。
(討論區的題解好像值考慮右區間的情況進行縮小範圍的,後面也貼上他的代碼)
class Solution:
def minArray(self, numbers: List[int]) -> int:
# 模擬二分
l = 0
r = len(numbers)-1
while l < r and numbers[l] >= numbers[r]:
m = (l + r) // 2
if numbers[l] < numbers[m]:
l = m + 1
elif numbers[l] > numbers[m]:
r = m
elif numbers[m] < numbers[r]:
r = m
elif numbers[m] > numbers[r]:
l = m + 1
else:
r -= 1
# print(l, r, m)
return numbers[l]
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
elif numbers[m] < numbers[j]: j = m
else: j -= 1
return numbers[i]
作者: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)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。