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

LeetCode 34: Find First and Last Position of Element in 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-21

  • 提交紀錄:Time Limit Exceeded ×5 → Runtime Error ×2 → Wrong Answer ×3 → Runtime Error → Wrong Answer ×2 → Accepted ×4 → Wrong Answer → Accepted ×2

解題思路
#

兩個邊界都可以用同一個 lower bound 函式(Binary Search 模板一):

  • 開頭:第一個 >= target 的位置。
  • 結尾:第一個 >= target + 1 的位置再減一。

開頭超出範圍或那個位置不是 target,就代表不存在。

我的嘗試
#

這題 2022 年提交了 20 次:

  • 前幾版用 while l < r 加上 l = mid / r = mid,區間縮不動,無限迴圈(TLE)。
  • 改好迴圈之後,最後用 start < end 判斷有沒有找到:只出現一次時開頭等於結尾,被當成不存在。例如 [1]、target = 1:答案 [0, 0],回傳 [-1, -1];有一版結尾用了 low 而不是 high,回傳 [0, 1]。

正確解法
#

class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        def lower(x):
            l, r = 0, len(nums)
            while l < r:
                mid = (l + r) // 2
                if nums[mid] < x:
                    l = mid + 1
                else:
                    r = mid
            return l
        start = lower(target)
        if start == len(nums) or nums[start] != target:
            return [-1, -1]
        return [start, lower(target + 1) - 1]

複雜度
#

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

要特別避免的錯誤
#

  • 只有一個元素時開頭和結尾一樣,不能用 start < end 判斷存不存在。
  • 找到之後不要停,要繼續往左(或往右)縮。

面試口說整理
#

我寫一個 lower bound,找第一個不小於目標的位置當開頭,再找第一個不小於目標加一的位置減一當結尾;開頭不是目標就回傳 [-1, -1]。兩次二分,時間 O(log n)。

相關文章

LeetCode 33: Search in Rotated Sorted Array
·1 分鐘
LeetCode Medium Array Binary-Search
LeetCode 33 解題筆記:旋轉後 mid 的左右一定有一邊是排序好的,判斷目標在不在那一邊,在就往那邊找,不在就去另一邊
LeetCode 31: Next Permutation
·1 分鐘
LeetCode Medium Array Two-Pointers
LeetCode 31 解題筆記:從右邊找第一個下降的位置 i,跟右邊比它大的最小值交換,再把 i 之後反轉;比較時要包含等於
LeetCode 36: Valid Sudoku
·1 分鐘
LeetCode Medium Array Hash-Table Matrix
LeetCode 36 解題筆記:每個數字在列、欄、3 × 3 宮格各只能出現一次;用 (數字, 列)、(數字, 欄)、(數字, 宮格) 當 key 放進同一個集合
LeetCode 39: Combination Sum
·1 分鐘
LeetCode Medium Array Backtracking
LeetCode 39 解題筆記:同一個數可以重複選,所以遞迴時下一層從 i 開始(不是 i + 1),這樣也避免了順序不同的重複
LeetCode 40: Combination Sum II
·1 分鐘
LeetCode Medium Array Backtracking
LeetCode 40 解題筆記:每個數只能用一次而且有重複,排序後下一層從 i + 1 開始,同一層跳過跟前一個相同的值
LeetCode 46: Permutations
·1 分鐘
LeetCode Medium Array Backtracking
LeetCode 46 解題筆記:每一層從還沒用過的數裡選一個,用 used 陣列標記,path 滿了就記錄