Skip to main content

Decode String

LeetCode 394 | Difficulty: Medium​

Medium

Problem Description​

Given an encoded string, return its decoded string.

The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guaranteed to be a positive integer.

You may assume that the input string is always valid; there are no extra white spaces, square brackets are well-formed, etc. Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there will not be input like 3a or 2[4].

The test cases are generated so that the length of the output will never exceed 10^5.

Example 1:

Input: s = "3[a]2[bc]"
Output: "aaabcbc"

Example 2:

Input: s = "3[a2[c]]"
Output: "accaccacc"

Example 3:

Input: s = "2[abc]3[cd]ef"
Output: "abcabccdcdcdef"

Constraints:

- `1 <= s.length <= 30`

- `s` consists of lowercase English letters, digits, and square brackets `'[]'`.

- `s` is guaranteed to be **a valid** input.

- All the integers in `s` are in the range `[1, 300]`.

Topics: String, Stack, Recursion


Approach​

Stack​

Use a stack (LIFO) to track elements that need future processing. Process elements when a "trigger" condition is met (e.g., finding a smaller/larger element). Monotonic stack maintains elements in sorted order for next greater/smaller element problems.

When to use

Matching brackets, next greater element, evaluating expressions, backtracking history.

String Processing​

Consider character frequency counts, two-pointer approaches, or building strings efficiently. For pattern matching, think about KMP or rolling hash. For palindromes, expand from center or use DP.

When to use

Anagram detection, palindrome checking, string transformation, pattern matching.


Solutions​

Solution 1: C# (Best: 84 ms)​

MetricValue
Runtime84 ms
Memory22.8 MB
Date2019-12-31
Solution
public class Solution {
public string DecodeString(string s) {
Stack<string> stack = new Stack<string>();
string currString = "", currNum = "";
foreach (char c in s)
{
if (c == '[')
{
stack.Push(currString);
stack.Push(currNum);
currString = "";
currNum = "";
}
else if (c == ']')
{
var num = stack.Pop();
var prevString = stack.Pop();
currString = prevString + string.Concat(Enumerable.Repeat(currString, Int32.Parse(num)));
}
else if (char.IsDigit(c))
{
currNum += c;
}
else
{
currString += c;
}
}

return currString;
}
}
πŸ“œ 2 more C# submission(s)

Submission (2022-01-05) β€” 96 ms, 34.9 MB​

public class Solution {
public string DecodeString(string s) {
Stack<string> stack = new Stack<string>();
string curString = "", curNum = "";
foreach (var c in s)
{
if(c == '[')
{
stack.Push(curString);
stack.Push(curNum);
curString = "";
curNum = "";
}
else if(c == ']')
{
string num = stack.Pop();
string prev = stack.Pop();
curString = prev + string.Concat(Enumerable.Repeat(curString, Int32.Parse(num)));
}
else if(char.IsDigit(c))
{
curNum += $"{c}";
}
else
{
curString += $"{c}";
}
}
return curString;
}
}

Submission (2019-12-31) β€” 104 ms, 21.7 MB​

public class Solution {
public string DecodeString(string s) {
Stack<string> stack = new Stack<string>();
string currString = "", currNum = "";
foreach (char c in s)
{
if (c == '[')
{
stack.Push(currString);
stack.Push(currNum);
currString = "";
currNum = "";
}
else if (c == ']')
{
var num = stack.Pop();
var prevString = stack.Pop();
currString = prevString + string.Concat(Enumerable.Repeat(currString, Int32.Parse(num)));
}
else if (char.IsDigit(c))
{
currNum += c;
}
else
{
currString += c;
}
}

return currString;
}
}

Complexity Analysis​

ApproachTimeSpace
Stack$O(n)$$O(n)$

Interview Tips​

Key Points
  • Discuss the brute force approach first, then optimize. Explain your thought process.
  • Think about what triggers a pop: is it finding a match, or finding a smaller/larger element?