Python 0394.py
class Solution:
def decodeString(self, s: str) -> str:
todo = []
num = ""
text = ""
for c in s:
if c == "[":
todo.append((int(num), text))
num = ""
text = ""
elif c == "]":
repeat, outer = todo.pop()
text = outer + text * repeat
elif c.isdigit():
num += c
else:
text += c
return text
Difficulty
and has an acceptance rate of about 63% (2+ million submissions).
Typical patterns to solve this problem:
- Recursion
- Stack
- String
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The provided implementation decodes an encoded string that follows the pattern k[encoded_string] where k is a positive integer indicating how many times encoded_string should be repeated. The algorithm processes the input in a single left-to-right pass, using a stack to keep track of pending repetitions and the partially built result for each nesting level. The final decoded string is returned after the loop finishes.
Initialization
At the start, three variables are prepared:
todo = []
num = ""
text = ""
todoacts as a stack that stores tuples of the form (repeat count, outer text) for each opened bracket.numaccumulates consecutive digit characters to form the repeat count.textholds the characters that belong to the current nesting level.
Main Loop
The core of the algorithm iterates over each character c in the input string s:
for c in s:
...
Inside the loop four distinct cases are distinguished.
Encountering an Opening Bracket
When c is '[', the current number and text are pushed onto the stack, and the accumulators are reset for the new inner segment:
if c == "[":
todo.append((int(num), text))
num = ""
text = ""
This step captures the repeat count (int(num)) and the string built so far (text) before descending into a deeper level.
Encountering a Closing Bracket
When c is ']', the most recent context is popped from the stack, the inner text is repeated, and then concatenated with the outer text that was saved earlier:
elif c == "]":
repeat, outer = todo.pop()
text = outer + text * repeat
The multiplication text * repeat expands the inner segment, and the result is attached to the outer segment, effectively collapsing one level of nesting.
Processing Digits
If the character is a digit, it is appended to num to allow multi-digit repeat counts:
elif c.isdigit():
num += c
By building the number as a string and converting it only when an opening bracket is seen, the code avoids repeated integer parsing.
Processing Alphabetic Characters
Any character that is not a bracket or a digit is treated as a literal part of the current segment and appended to text:
else:
text += c
This includes lower-case letters, upper-case letters, and any other non-digit, non-bracket symbols that may appear in the encoded string.
Final Result
After the loop completes, text contains the fully decoded string, which is returned directly:
return text
If the input string contains no brackets, the loop never pushes or pops from the stack, and text simply accumulates the original characters, resulting in an identity transformation.
Edge Cases Handled
The algorithm gracefully manages several edge conditions:
- Nested encodings such as
"3[a2[b]]"are decoded correctly because each'['pushes a new context and each']'pops and resolves the most recent one, preserving the proper order of expansion. - Multi-digit repeat counts like
"12[ab]"are supported because digits are concatenated intonumuntil the opening bracket signals conversion to an integer. - Empty inner sections (e.g.,
"2[]") produce an empty string for that segment, and the outer concatenation still respects the repeat count, yielding an empty contribution. - Strings without any brackets (e.g.,
"hello") bypass the stack logic entirely, returning the original string unchanged. - Consecutive literals after a closing bracket (e.g.,
"2[ab]c") are appended totextafter the inner segment is resolved, ensuring correct ordering.
Performance Optimizations Observed
- Single pass processing eliminates the need for multiple scans or recursive calls, keeping the runtime proportional to the length of the input.
- Stack reuse via a Python list (
todo) provides O(1) push and pop operations, which is efficient for deep nesting. - Deferred integer conversion occurs only when an opening bracket is encountered, reducing the number of
int()calls compared with converting each digit individually. - Local variable usage (
num,text,repeat,outer) minimizes attribute lookups and speeds up the loop body. - String multiplication (
text * repeat) leverages Python’s optimized C implementation for repeating sequences, avoiding manual concatenation loops.
These choices collectively ensure that the function runs quickly even for long strings with many nested repetitions.
ELI5 - Simplified Explanation
Imagine a magical box that knows how to follow secret instructions written in a special code. Sometimes the instruction says to write a word, but other times it says to repeat a word many times.
The computer starts with an empty notebook called todo and two empty slates called num and text. It looks at every symbol in the string one by one.
When the computer sees a number, it writes that digit on the num slate so it remembers how many times to do the trick later.
When it sees an opening bracket, it knows a secret message is about to start. It takes the number it found and puts it into the notebook along with any words it has gathered so far. After that, it cleans the slates so they are ready for the new part of the message.
When it sees a normal letter like a or b, it puts that letter onto the text slate.
When it sees a closing bracket, the magic happens. It takes the last number and the old words out of the notebook. It takes the words it just finished building and repeats them as many times as the number says. Then it sticks that long string onto the end of the old words it saved earlier.
The computer does this over and over until it has finished reading every single part of the instructions. By the end, all the pieces are put together into one long, finished sentence.
Code Quality
Complexity Analysis
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| author | solutions | |||||||||||||
| www | AlgoMonster | C++ | Java | Python | TS | |||||||||
| WalkCCC | C++ | Java | Python | |||||||||||
| leetcode.ca | Java | Python | TS | |||||||||||
| LeetcodeHelp | C++ | Java | Python | |||||||||||
| Progiez | C++ | Java | Python | |||||||||||
| github | AdelDaniel | Dart | ||||||||||||
| BigEggStudy | C# | |||||||||||||
| black-shadows | C++ | |||||||||||||
| charles-wangkai | Java | |||||||||||||
| everthis | JS | |||||||||||||
| fartem | Ruby | |||||||||||||
| FelixFan1122 | C# | |||||||||||||
| fengvyi | C++ | |||||||||||||
| fpdjsns | C++ | |||||||||||||
| gouthampradhan | Java | |||||||||||||
| halfrost | Go | |||||||||||||
| haoel | C++ | |||||||||||||
| JoshCrozier | JS | |||||||||||||
| keineahnung2345 | C++ | |||||||||||||
| linouk23 | C++ | |||||||||||||
| lkwq007 | Python | |||||||||||||
| luangong | TS | |||||||||||||
| MacJim | C++ | |||||||||||||
| martianoff | Scala | |||||||||||||
| ruoru | Rust | |||||||||||||
| suxrobGM | C# | |||||||||||||
| trung-hn | Python | |||||||||||||
| varunu28 | Java | |||||||||||||
| vli02 | C | |||||||||||||
| vthwang | Java | |||||||||||||
| XiaotaoGuo | C++ | |||||||||||||
| yuanliu666 | Kotlin | |||||||||||||
| YuriSpiridonov | Python | |||||||||||||
| AlgoMonster | C++, Python, Java, TypeScript | |||||||||||||
| WalkCCC | C++, Python, Java | |||||||||||||
| leetcode.ca | Java, Python, TypeScript | |||||||||||||
| LeetcodeHelp | C++, Java, Python | |||||||||||||
| Progiez | C++, Java, Python | |||||||||||||
| AdelDaniel | Dart | |||||||||||||
| BigEggStudy | C# | |||||||||||||
| black-shadows | C++, C++ | |||||||||||||
| charles-wangkai | Java | |||||||||||||
| everthis | JavaScript | |||||||||||||
| fartem | Ruby | |||||||||||||
| FelixFan1122 | C# | |||||||||||||
| fengvyi | C++ | |||||||||||||
| fpdjsns | C++ | |||||||||||||
| gouthampradhan | Java | |||||||||||||
| halfrost | Go | |||||||||||||
| haoel | C++ | |||||||||||||
| JoshCrozier | JavaScript | |||||||||||||
| keineahnung2345 | C++ | |||||||||||||
| linouk23 | C++ | |||||||||||||
| lkwq007 | Python | |||||||||||||
| luangong | TypeScript | |||||||||||||
| MacJim | C++ | |||||||||||||
| martianoff | Scala | |||||||||||||
| ruoru | Rust | |||||||||||||
| suxrobGM | C# | |||||||||||||
| trung-hn | Python | |||||||||||||
| varunu28 | Java | |||||||||||||
| vli02 | C | |||||||||||||
| vthwang | Java | |||||||||||||
| XiaotaoGuo | C++ | |||||||||||||
| yuanliu666 | Kotlin | |||||||||||||
| YuriSpiridonov | Python |
Videos
Similar Problems
- problem 471: Encode String with Shortest Length
Solved On The Same Day
- problem 415: Add Strings
- problem 463: Island Perimeter
- problem 541: Reverse String II
- problem 1211: Queries Quality and Percentage
- problem 1251: Average Selling Price
- problem 1280: Students and Examinations
- problem 1327: List the Products Ordered in a Period
- problem 1378: Replace Employee ID With The Unique Identifier
- problem 1407: Top Travellers
- problem 1484: Group Sold Products By The Date
- problem 1517: Find Users With Valid E-Mails
- problem 1527: Patients With a Condition
- problem 1581: Customer Who Visited but Did Not Make Any Transactions
- problem 1587: Bank Account Summary II
- problem 1633: Percentage of Users Attended a Contest
- problem 1661: Average Time of Process per Machine
- problem 1667: Fix Names in a Table
- problem 1683: Invalid Tweets
- problem 1693: Daily Leads and Partners
- problem 1729: Find Followers Count
- problem 1731: The Number of Employees Which Report to Each Employee
- problem 1741: Find Total Time Spent by Each Employee
- problem 1757: Recyclable and Low Fat Products
- problem 1789: Primary Department for Each Employee
- problem 1795: Rearrange Products Table
- problem 1873: Calculate Special Bonus
- problem 1890: The Latest Login in 2020
- problem 1965: Employees With Missing Information
- problem 1978: Employees Whose Manager Left the Company
- problem 2356: Number of Unique Subjects Taught by Each Teacher
- problem 166: Fraction to Recurring Decimal
- problem 223: Rectangle Area
- problem 240: Search a 2D Matrix II
- problem 318: Maximum Product of Word Lengths
- problem 357: Count Numbers with Unique Digits
- problem 1158: Market Analysis I
- problem 1341: Movie Rating
- problem 1492: The kth Factor of n
- problem 1498: Number of Subsequences That Satisfy the Given Sum Condition
- problem 1907: Count Salary Categories
- problem 1934: Confirmation Rate
- problem 2405: Optimal Partition of String
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality