↓Skip to main content
  1. LeetCode/

LeetCode 2904: Shortest and Lexicographically Smallest Beautiful String

·2 mins· ·
LeetCode Medium Sliding-Window String
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2026-01-18

  • Submissions: Wrong Answer → Accepted

Approach
#

The shortest beautiful substring always starts and ends with 1 (zeros at either end can be dropped).

Sliding window: add on the right, and shrink the left while there are more than k ones, or exactly k with a 0 at the left end. If exactly k ones remain, this is the shortest candidate ending at right.

Compare candidates by length first, and lexicographically only on equal length.

My Attempts
#

Attempt 1 compared with len(ans) > len(target) or ans > target, replacing the answer whenever the candidate was lexicographically smaller, regardless of length. For s = "1101", k = 2, the shortest is "11", but "101" is lexicographically smaller than "11", so it returned "101".

Solution
#

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

Complexity
#

Time O(n^2) (comparing candidates is up to O(n)), with n <= 100. Space O(n).

Mistakes to Avoid
#

  • Comparing lexicographically without checking length first.
  • "101" < "11": strings compare character by character, not by length.

Interview Explanation
#

The shortest beautiful substring starts and ends with 1. I slide a window, shrinking the left while there are more than k ones or exactly k with a leading 0; exactly k ones then gives the shortest candidate ending at the right end. Candidates compare by length first, and lexicographically only on ties.

Related

LeetCode 395: Longest Substring with At Least K Repeating Characters
·3 mins
LeetCode Medium Sliding-Window Divide-and-Conquer Hash-Table String
LeetCode 395 note: “every character at least k times” is not monotonic, so a direct slide fails; divide and conquer splits on characters with fewer than k occurrences, or fixing the number of distinct characters makes the window slidable
LeetCode 2516: Take K of Each Character From Left and Right
·2 mins
LeetCode Medium Sliding-Window Hash-Table String
LeetCode 2516 note: taking from both ends leaves a middle block in which each letter may appear at most total − k times; find the longest such window
LeetCode 1016: Binary String With Substrings Representing 1 To N
·3 mins
LeetCode Medium Sliding-Window String Bit-Manipulation Hash-Table
LeetCode 1016 note: s has at most 1000 characters, so there are few substrings of any fixed length and a large n must be False; checking from n downward fails fast, or extend up to 30 bits from each start to collect every value <= n
LeetCode 1888: Minimum Number of Flips to Make the Binary String Alternating
·2 mins
LeetCode Medium Sliding-Window String Dynamic-Programming
LeetCode 1888 note: rotations become length-n windows over s + s; the window’s mismatches against 0101… are diff, and against 1010… they are n - diff
LeetCode 3694: Distinct Points Reachable After Substring Removal
·2 mins
LeetCode Medium Sliding-Window Prefix-Sum Hash-Table String
LeetCode 3694 note: the endpoint is the total displacement minus the removed segment’s displacement; a length-k window tracks that segment and each endpoint goes into a set
LeetCode 187: Repeated DNA Sequences
·1 min
LeetCode Medium Hash-Table String Bit-Manipulation Sliding-Window
LeetCode 187 note: count every length-10 substring in a hash map and return those seen more than once