假設按照升序排序的數組在預先未知的某個點上進行了旋轉。
( 例如,數組 [0,1,2,4,5,6,7] 可能變爲 [4,5,6,7,0,1,2] )。
請找出其中最小的元素。
你可以假設數組中不存在重複元素。
示例 1:
輸入: [3,4,5,1,2]
輸出: 1
示例 2:
輸入: [4,5,6,7,0,1,2]
輸出: 0
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
思路: 首先這個數組在局部上仍是有序的,只是被分爲了前後兩個有序的部分。
我們可以知道,當一個有序數組被旋轉之後,前半部分和後半部分分別有序,並且前半部分的值必定大於後半部分,並且題目所求最小數字位於前半部分與後半部分的交界處。
如何定位最小數字的位置,我們使用二分時,會選出一個Mid值進行一定條件的比較,以判斷向某個方向縮小搜索範圍。
此時我們有一個位於中間的數字mid,可以將其與最左邊的數進行比較,當發現大於最左邊的數時,說明當前mid的值位於有序數組的前半部分,這是顯而易見的,因爲若該mid位置的值小於最左邊的值,那麼明顯是後半部分的值,因爲前半部分的所有值都大於等於後半部分的值。由此定位到我們正搜索的位置,並且我們知道,最小值位於右半部分的第一個值,,位於左半部分的最後一個值之後。
通過比較左右邊界的大小的信息,我們容易得出目標值位於左邊還是右邊,當Mid大於左邊界的值時,向右搜索,儘量使搜索範圍靠近右半部分。
當mid的值小於左邊界時,該值一定位於右半部分,此時可能當前值以及當前值的左邊存在目標值。於是向左搜索。
在二分的過程中,我們可以多次判斷當前值與前後兩值的關係,當前一個值大於當前值,或後一個值小於當前值時【不滿足單調遞增的性質】說明已經找到了兩部分的邊界,可以直接返回結果
class Solution:
def findMin(self, nums: List[int]) -> int:
if nums[0]<=nums[-1]:
return nums[0]
l=0
r=len(nums)-1
while l<=r:
mid=(l+r)//2
if nums[mid]>nums[mid+1]:
return nums[mid+1]
if nums[mid]<nums[mid-1]:
return nums[mid]
if nums[mid]>nums[l] :
l=mid+1
else:r=mid-1