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

LeetCode 3694: Distinct Points Reachable After Substring Removal

·1 分鐘· ·
LeetCode Medium Sliding-Window Prefix-Sum Hash-Table String
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2025-12-27

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

解題思路
#

移動是向量相加,順序不影響終點。刪掉一段長度 k 的子字串後:

終點 = 整個字串的位移 − 被刪掉那段的位移

所以先算整個字串的總位移,再用長度 k 的固定視窗維護「視窗內的位移」,每個視窗算出一個終點放進 set,答案是 set 的大小。

我的嘗試
#

第一版更新答案的條件寫在 if i - k >= 0 裡面,也就是只有視窗滿了而且已經移出一個元素之後才記錄,少了第一個視窗(刪掉 s[0..k-1])。例如 s = "UL"、k = 1:刪 U 剩 L 到 (-1, 0),刪 L 剩 U 到 (0, 1),答案是 2;這版只記到後者,回傳 1。

把「移出元素」和「記錄終點」分開,記錄的條件改成 i - k + 1 >= 0 就 AC 了。

正確解法
#

class Solution:
    def distinctPoints(self, s: str, k: int) -> int:
        move = {"U": (0, 1), "D": (0, -1), "L": (-1, 0), "R": (1, 0)}
        total_x = sum(move[c][0] for c in s)
        total_y = sum(move[c][1] for c in s)

        wx = wy = 0                                # 視窗內的位移
        points = set()
        for i, c in enumerate(s):
            wx += move[c][0]
            wy += move[c][1]
            if i >= k:
                out = s[i - k]
                wx -= move[out][0]
                wy -= move[out][1]
            if i >= k - 1:                         # 第一個視窗在 i == k - 1
                points.add((total_x - wx, total_y - wy))
        return len(points)

k == n 時只有一個視窗,終點是 (0, 0),不需要另外特判。

複雜度
#

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

要特別避免的錯誤
#

  • 漏掉第一個視窗:記錄答案的條件是 i >= k - 1,移出元素的條件是 i >= k,兩個要分開。

面試口說整理
#

移動是向量相加,所以刪掉一段之後的終點等於總位移減掉那段的位移。我先算總位移,再用長度 k 的滑動視窗維護視窗內的位移,每個視窗算出一個終點放進 set。注意第一個視窗在 i == k - 1 就要記錄。時間 O(n)。

相關文章

LeetCode 1248: Count Number of Nice Subarrays
·2 分鐘
LeetCode Medium Sliding-Window Prefix-Sum Hash-Table Array
LeetCode 1248 解題筆記:「剛好 k 個奇數」不單調,改成「最多 k 個」減「最多 k - 1 個」;或用前綴和 + 雜湊表
LeetCode 187: Repeated DNA Sequences
·1 分鐘
LeetCode Medium Hash-Table String Bit-Manipulation Sliding-Window
LeetCode 187 解題筆記:把每個長度 10 的子字串丟進雜湊表計數,出現超過一次的就是答案
LeetCode 424: Longest Repeating Character Replacement
·1 分鐘
LeetCode Medium Hash-Table String Sliding-Window
LeetCode 424 解題筆記:可變長度滑動視窗,視窗長度減掉最多的字元次數就是要替換的數量,超過 k 就縮左邊
LeetCode 3679: Minimum Discards to Balance Inventory
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table Simulation Counting Array
LeetCode 3679 解題筆記:規則已經決定哪些要丟,直接模擬;長度 w 的視窗只計算「留下來」的到貨,被丟掉的離開視窗時不能再扣
LeetCode 2841: Maximum Sum of Almost Unique Subarray
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table Array
LeetCode 2841 解題筆記:固定長度 k 的視窗,維護總和與計數雜湊表;不同值的個數就是雜湊表的大小,數量歸零要刪 key
LeetCode 2131: Longest Palindrome by Concatenating Two Letter Words
·1 分鐘
LeetCode Medium Greedy Hash-Table String Counting
LeetCode 2131 解題筆記:每個字跟它的反轉配成一對放兩邊;本身是回文的字也能兩兩配對,只有剩下的一個能放正中間