↓快轉到主要內容
  1. LeetCode/

LeetCode 153: Find Minimum in Rotated Sorted Array

·1 分鐘· ·
LeetCode Medium Array Binary-Search
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2022-10-28

  • 提交紀錄:Wrong Answer → Accepted ×2 → Wrong Answer ×6 → Accepted → Wrong Answer ×2 → Accepted ×4

解題思路
#

最小值是旋轉的斷點。拿 nums[mid] 跟 nums[r] 比(Binary Search):

  • nums[mid] > nums[r]:斷點在 mid 右邊,l = mid + 1。
  • 否則 [mid, r] 是遞增的,最小值在 mid 或它的左邊,r = mid。

用 while l < r,最後 l == r 就是最小值。跟右端比比較不會錯:跟左端比時,沒有旋轉的陣列要另外處理。

我的嘗試
#

前面 9 次 WA 都是拿 nums[mid] 跟左端比,條件組合不完整,只有兩個元素的旋轉陣列就錯了,例如 [5, 4] 回傳 5。改成跟右端比就簡單多了。

正確解法
#

class Solution:
    def findMin(self, nums: List[int]) -> int:
        l, r = 0, len(nums) - 1
        while l < r:
            mid = (l + r) // 2
            if nums[mid] > nums[r]:
                l = mid + 1
            else:
                r = mid
        return nums[l]

複雜度
#

時間 O(log n),空間 O(1)。

要特別避免的錯誤
#

  • r = mid 不是 mid - 1:mid 本身可能就是最小值。

面試口說整理
#

最小值是斷點,所以我拿中間跟右端比:中間比較大代表斷點在右邊,否則最小值在中間或左邊,把右界縮到中間。最後左右界相遇的位置就是最小值。時間 O(log n)。

相關文章

LeetCode 875: Koko Eating Bananas
·1 分鐘
LeetCode Medium Array Binary-Search
LeetCode 875 解題筆記:對速度二分,找最小的 k 讓總時數 <= h;時數剛好等於 h 時還要繼續往左找
LeetCode 167: Two Sum II - Input Array Is Sorted
·1 分鐘
LeetCode Medium Array Two-Pointers Binary-Search
LeetCode 167 解題筆記:已排序,左右指針往中間走:和太大右指針左移,太小左指針右移;回傳的 index 從 1 開始
LeetCode 81: Search in Rotated Sorted Array II
·1 分鐘
LeetCode Medium Array Binary-Search
LeetCode 81 解題筆記:有重複值時 nums[l] == nums[mid] 會分不出哪一半有序,這時只能把 l 往右移一格;最壞 O(n)
LeetCode 74: Search a 2D Matrix
·1 分鐘
LeetCode Medium Array Binary-Search Matrix
LeetCode 74 解題筆記:每列接上一列是完整排序的,把矩陣當成長度 m × n 的一維陣列二分,mid 換成 (mid // n, mid % n)
LeetCode 33: Search in Rotated Sorted Array
·1 分鐘
LeetCode Medium Array Binary-Search
LeetCode 33 解題筆記:旋轉後 mid 的左右一定有一邊是排序好的,判斷目標在不在那一邊,在就往那邊找,不在就去另一邊
LeetCode 34: Find First and Last Position of Element in Sorted Array
·1 分鐘
LeetCode Medium Array Binary-Search
LeetCode 34 解題筆記:做兩次 lower bound:第一個 >= target 的位置,以及第一個 >= target + 1 的位置減一