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

LeetCode 2904: Shortest and Lexicographically Smallest Beautiful String

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

基本資料
#

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

  • 提交紀錄:Wrong Answer → Accepted

解題思路
#

最短的美麗子字串一定頭尾都是 1(頭尾的 0 可以拿掉)。

滑動視窗:右端加入字元,1 超過 k 個、或剛好 k 個但左端是 0,就縮左邊。縮完後如果剛好 k 個 1,這就是以 right 結尾最短的候選。

比較候選時,先比長度,長度相同才比字典序。

我的嘗試
#

第一版的比較寫成 len(ans) > len(target) or ans > target:只要字典序比較小就取代,不管長度。例如 s = "1101"、k = 2:最短的是 "11",但 "101" 的字典序比 "11" 小,結果回傳 "101"。

正確解法
#

class Solution:
    def shortestBeautifulSubstring(self, s: str, k: int) -> str:
        left = ones = 0
        ans = ""
        for right, c in enumerate(s):
            ones += c == "1"
            while ones > k or (ones == k and s[left] == "0"):
                ones -= s[left] == "1"
                left += 1
            if ones == k:
                cand = s[left:right + 1]
                if not ans or len(cand) < len(ans) or (len(cand) == len(ans) and cand < ans):
                    ans = cand
        return ans

複雜度
#

時間 O(n^2)(比較候選字串最多 O(n)),n <= 100。空間 O(n)。

要特別避免的錯誤
#

  • 只比字典序,沒有先比長度。
  • "101" < "11":字串比較是逐字比,不是比長度。

面試口說整理
#

最短的美麗子字串頭尾一定是 1。我用滑動視窗,1 超過 k 個或剛好 k 個但左端是 0 時縮左邊,縮完剛好 k 個 1 就是以右端結尾最短的候選。比較時先看長度,長度一樣才比字典序。

相關文章

LeetCode 395: Longest Substring with At Least K Repeating Characters
·2 分鐘
LeetCode Medium Sliding-Window Divide-and-Conquer Hash-Table String
LeetCode 395 解題筆記:「每個字元至少 k 次」不單調,不能直接滑動;分治法用出現不到 k 次的字元切開,或枚舉視窗裡有幾種字元,固定種類數後就能滑動
LeetCode 2516: Take K of Each Character From Left and Right
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table String
LeetCode 2516 解題筆記:從兩端拿等於中間留一段;留下的每種字元最多是總數 − k,找最長的這種中間視窗
LeetCode 1016: Binary String With Substrings Representing 1 To N
·2 分鐘
LeetCode Medium Sliding-Window String Bit-Manipulation Hash-Table
LeetCode 1016 解題筆記:s 最多 1000 個字元,長度固定時的子字串數量有限,n 太大一定是 False;從 n 往下檢查會很快失敗,或從每個起點往右最多延伸 30 位收集所有 <= n 的值
LeetCode 1888: Minimum Number of Flips to Make the Binary String Alternating
·1 分鐘
LeetCode Medium Sliding-Window String Dynamic-Programming
LeetCode 1888 解題筆記:把移到尾巴的操作變成在 s + s 上滑動長度 n 的視窗;視窗跟 0101… 不同的數量是 diff,跟 1010… 不同的就是 n - diff
LeetCode 3694: Distinct Points Reachable After Substring Removal
·1 分鐘
LeetCode Medium Sliding-Window Prefix-Sum Hash-Table String
LeetCode 3694 解題筆記:終點 = 全部的位移 − 被刪掉那段的位移;用長度 k 的視窗維護那段的位移,把每個終點放進 set
LeetCode 187: Repeated DNA Sequences
·1 分鐘
LeetCode Medium Hash-Table String Bit-Manipulation Sliding-Window
LeetCode 187 解題筆記:把每個長度 10 的子字串丟進雜湊表計數,出現超過一次的就是答案