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

LeetCode 2972: Count the Number of Incremovable Subarrays II

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

基本資料
#

難易度: hard 第一次嘗試:2026-01-26

  • 提交紀錄:Accepted ×2

解題思路
#

跟 LeetCode 1574 同一個結構,只是這題要數有幾種刪法,而且要嚴格遞增。

刪掉 nums[l..r] 後,留下的前綴 nums[0..l-1] 和後綴 nums[r+1..] 都要嚴格遞增,而且 nums[l-1] < nums[r+1](有一邊是空的就不用比)。

  1. 從右邊找最長的嚴格遞增後綴,起點 right。如果整個陣列都是,任何非空子陣列都能刪,答案是 n(n + 1) / 2。
  2. 前綴是空的:後綴的起點可以是 right, right + 1, ..., n(n 代表後綴也是空的),共 n - right + 1 種。
  3. 前綴到 left(nums[0..left] 要嚴格遞增):後綴起點要 > left 而且 nums[起點] > nums[left]。讓 right 往右走到第一個 nums[right] > nums[left],之後的起點都可以,共 n - right + 1 種。

left 越大,nums[left] 越大,能接的後綴起點只會往右,所以 right 不用回頭。

我的解法
#

class Solution:
    def incremovableSubarrayCount(self, nums: List[int]) -> int:
        n = len(nums)
        right = n - 1
        while right > 0 and nums[right - 1] < nums[right]:
            right -= 1
        if right == 0:
            return n * (n + 1) // 2                # 整個陣列嚴格遞增

        ans = n - right + 1                        # 前綴是空的
        for left in range(n):
            if left > 0 and nums[left - 1] >= nums[left]:
                break                              # 前綴不再嚴格遞增
            while right < n and nums[right] <= nums[left]:
                right += 1
            ans += n - right + 1                   # 後綴起點 right..n 都可以
        return ans

複雜度
#

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

要特別避免的錯誤
#

  • 忘了「前綴是空的」和「後綴是空的」這兩種情況(n - right + 1 裡的 +1 就是後綴為空)。
  • 這題是嚴格遞增,比較要用 <,跟 1574 的 <= 不一樣。
  • 整個陣列已經遞增時要特判,否則 right 和 left 會重疊。

面試口說整理
#

刪掉一段之後留下的是前綴加後綴,兩段都要嚴格遞增、接起來也要遞增。我先找出最長的嚴格遞增後綴;前綴為空時後綴起點有 n - right + 1 種。接著依序把前綴延長到 left,讓後綴指針往右走到第一個比 nums[left] 大的位置,從那裡開始的起點都能接,也是 n - right + 1 種。兩個指針都不回頭,時間 O(n)。

相關文章

LeetCode 1574: Shortest Subarray to be Removed to Make Array Sorted
·1 分鐘
LeetCode Medium Two-Pointers Binary-Search Array Monotonic-Stack
LeetCode 1574 解題筆記:留下來的一定是「非遞減前綴 + 非遞減後綴」;先找出最長前綴和後綴,再用雙指針把兩段接起來
LeetCode 2302: Count Subarrays With Score Less Than K
·1 分鐘
LeetCode Hard Sliding-Window Prefix-Sum Binary-Search Array
LeetCode 2302 解題筆記:分數 = 總和 × 長度,都是正數,視窗越大分數越大;分數 >= k 就縮左邊,以 right 結尾的合法子陣列有 right - left + 1 個
LeetCode 2968: Apply Operations to Maximize Frequency Score
·1 分鐘
LeetCode Hard Sliding-Window Sorting Prefix-Sum Binary-Search Array
LeetCode 2968 解題筆記:排序後,把一段全部變成同一個值,最省的目標是中位數;用前綴和 O(1) 算花費,花費隨視窗變大而變大,可以滑動
LeetCode 2122: Recover the Original Array
·2 分鐘
LeetCode Hard Two-Pointers Sorting Hash-Table Enumeration Array
LeetCode 2122 解題筆記:最小的數一定在 lower,枚舉它的配對決定 k;排序後用兩個指針把每個最小的未配對數配給 +2k 的數
LeetCode 2563: Count the Number of Fair Pairs
·2 分鐘
LeetCode Medium Two-Pointers Sorting Binary-Search Array
LeetCode 2563 解題筆記:把「和落在 [lower, upper]」拆成「和 <= upper」減「和 <= lower - 1」,每個都用排序後的對撞指針 O(n) 數
LeetCode 1498: Number of Subsequences That Satisfy the Given Sum Condition
·2 分鐘
LeetCode Medium Two-Pointers Sorting Binary-Search Array
LeetCode 1498 解題筆記:子序列只看最小值和最大值,排序後順序無關;固定最小值 nums[left],中間的元素任意選,共 2^(right - left) 種