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

LeetCode 581: Shortest Unsorted Continuous Subarray

·1 分鐘· ·
LeetCode Medium Two-Pointers Greedy Sorting Array Monotonic-Stack
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2026-01-29

  • 提交紀錄:Accepted ×2

解題思路
#

要排序的範圍 [start, end] 是:

  • 右界 end:從左往右掃、記錄目前最大值 max_seen。如果 nums[i] < max_seen,代表 nums[i] 左邊有比它大的數,它一定要被排序,所以 end = i。最後一個這樣的 i 就是右界。
  • 左界 start:對稱地從右往左掃、記錄最小值 min_seen,最後一個 nums[i] > min_seen 的 i 就是左界。

右界右邊的每個數都 >= 前面所有數,而且本身遞增,所以已經在正確位置;左界同理。

這兩次掃描就像從兩端往內找第一個「放錯位置」的數,只是比較對象是「另一側的最值」而不是相鄰元素。

我的解法
#

class Solution:
    def findUnsortedSubarray(self, nums: List[int]) -> int:
        n = len(nums)
        max_seen, end = float("-inf"), -1
        for i in range(n):
            if nums[i] < max_seen:
                end = i                            # 左邊有比它大的數
            else:
                max_seen = nums[i]
        if end == -1:
            return 0                               # 已經排好

        min_seen, start = float("inf"), -1
        for i in range(n - 1, -1, -1):
            if nums[i] > min_seen:
                start = i                          # 右邊有比它小的數
            else:
                min_seen = nums[i]
        return end - start + 1

複雜度
#

時間 O(n),空間 O(1)。另一種直覺解法是複製一份排序後比對兩端第一個不同的位置,O(n log n)。

要特別避免的錯誤
#

  • 只比較相鄰元素找第一個下降的位置:例如 [1, 3, 2, 0],範圍要延伸到 0 前面所有比它大的數,答案是整個陣列 4。
  • 已經排好時要回傳 0,不是 end - start + 1。

面試口說整理
#

我從左往右記錄最大值,最後一個比目前最大值小的位置就是右界,因為它左邊有更大的數;再從右往左記錄最小值,最後一個比目前最小值大的位置就是左界。兩次線性掃描,時間 O(n),空間 O(1)。

相關文章

LeetCode 3555: Smallest Subarray to Sort in Every Sliding Window
·1 分鐘
LeetCode Medium Two-Pointers Greedy Sorting Array Monotonic-Stack
LeetCode 3555 解題筆記:每個長度 k 的視窗都是一次 LeetCode 581;n 只有 1000,對每個視窗跑 O(k) 的兩次掃描即可
LeetCode 1877: Minimize Maximum Pair Sum in Array
·1 分鐘
LeetCode Medium Two-Pointers Greedy Sorting Array
LeetCode 1877 解題筆記:排序後最小配最大、次小配次大,對撞指針取配對和的最大值
LeetCode 948: Bag of Tokens
·1 分鐘
LeetCode Medium Two-Pointers Greedy Sorting Array
LeetCode 948 解題筆記:排序後,用最小的 token 換分數、用最大的 token 換能量;只有分數 > 0 才能換能量,換不了就停
LeetCode 2410: Maximum Matching of Players With Trainers
·1 分鐘
LeetCode Medium Two-Pointers Greedy Sorting Array
LeetCode 2410 解題筆記:兩邊都排序後,用同向雙指針讓最弱的球員配最小的、夠用的教練
LeetCode 1574: Shortest Subarray to be Removed to Make Array Sorted
·1 分鐘
LeetCode Medium Two-Pointers Binary-Search Array Monotonic-Stack
LeetCode 1574 解題筆記:留下來的一定是「非遞減前綴 + 非遞減後綴」;先找出最長前綴和後綴,再用雙指針把兩段接起來
LeetCode 1838: Frequency of the Most Frequent Element
·1 分鐘
LeetCode Medium Sliding-Window Sorting Greedy Prefix-Sum Binary-Search Array
LeetCode 1838 解題筆記:排序後,把視窗裡的數都加到 nums[right] 的花費是 nums[right] × 長度 − 視窗總和;花費 > k 就縮左邊