leetcode 旋轉數組的最小數字【二分】

假設按照升序排序的數組在預先未知的某個點上進行了旋轉。

( 例如,數組 [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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章