Stack

Decode String

medium

DESCRIPTION (inspired by Leetcode.com)

Given an encoded string, write a function to return its decoded string that follows a specific encoding rule: k[encoded_string], where the encoded_string within the brackets is repeated exactly k times. Note that k is always a positive integer. The input string is well-formed without any extra spaces, and square brackets are properly matched. Also, assume that the original data doesn't contain digits other than the ones that specify the number of times to repeat the following encoded_string.

Inputs:

s = "3[a2[c]]"

Output:

"accaccacc"

Explanation

We start by initializing our stack, and the variables curr_string and current_number. The stack allows us to account for nested sequences correctly. curr_string represents the current string we currently decoding, and current_number represents the number of times we need to repeat it when the current decode sequence is completed (i.e. when we encounter a closing "]" bracket).
Visualization
def decodeString(s):
stack = []
curr_string = ""
current_number = 0
for char in s:
if char == "[":
stack.append(curr_string)
stack.append(current_number)
curr_string = ""
current_number = 0
elif char == "]":
num = stack.pop()
prev_string = stack.pop()
curr_string = prev_string + num * curr_string
elif char.isdigit():
current_number = current_number * 10 + int(char)
else:
curr_string += char
return curr_string
3[a2[c]]

decode string

0 / 1

We then iterate over each character in the encoded string, handling each character as follows:

"[": Start of a new sequence

When we encounter an opening bracket, we push the current string curr_string and the current number current_number to the stack and reset curr_string to an empty string and current_number to 0. These values that we pushed onto the stack represent the "context" of the current sequence we are decoding. We use current_number to keep track of the number of times we need to repeat the current string we are about to decode, while curr_string represents the value of the string that will be prepended to the result of the current sequence.
Visualization
def decodeString(s):
stack = []
curr_string = ""
current_number = 0
for char in s:
if char == "[":
stack.append(curr_string)
stack.append(current_number)
curr_string = ""
current_number = 0
elif char == "]":
num = stack.pop()
prev_string = stack.pop()
curr_string = prev_string + num * curr_string
elif char.isdigit():
current_number = current_number * 10 + int(char)
else:
curr_string += char
return curr_string
3[a2[c]]stackcurrString: ""currNumber: 3

[

0 / 2

"]": End of a sequence

When we encounter a closing bracket, we pop the last element from the stack and repeat the current string curr_string by the number of times current_number and append it to the string at the top of the stack.
Visualization
def decodeString(s):
stack = []
curr_string = ""
current_number = 0
for char in s:
if char == "[":
stack.append(curr_string)
stack.append(current_number)
curr_string = ""
current_number = 0
elif char == "]":
num = stack.pop()
prev_string = stack.pop()
curr_string = prev_string + num * curr_string
elif char.isdigit():
current_number = current_number * 10 + int(char)
else:
curr_string += char
return curr_string
3[a2[c]]""3a2stackcurrString: ccurrNumber: 0

]

0 / 1

We are finished decoding 2[c], so we repeat \"c\"2 times and prepend \"a\" and pop the top two values from the stack.

Digit

When char is a digit, we update current_number by multiplying it by 10 and adding the value of the digit. current_number is used to keep track of the number of times we need to repeat the current string we are just about to decode.
Visualization
def decodeString(s):
stack = []
curr_string = ""
current_number = 0
for char in s:
if char == "[":
stack.append(curr_string)
stack.append(current_number)
curr_string = ""
current_number = 0
elif char == "]":
num = stack.pop()
prev_string = stack.pop()
curr_string = prev_string + num * curr_string
elif char.isdigit():
current_number = current_number * 10 + int(char)
else:
curr_string += char
return curr_string
3[a2[c]]stackcurrString: ""currNumber: 0

initialize variables

0 / 2

We need to repeat the result of decoding a2[c] 3 times.

Letter

When we encounter a letter, we append it to the current string curr_string.

Solution

|
string
Try these examples:
Visualization
def decodeString(s):
stack = []
curr_string = ""
current_number = 0
for char in s:
if char == "[":
stack.append(curr_string)
stack.append(current_number)
curr_string = ""
current_number = 0
elif char == "]":
num = stack.pop()
prev_string = stack.pop()
curr_string = prev_string + num * curr_string
elif char.isdigit():
current_number = current_number * 10 + int(char)
else:
curr_string += char
return curr_string
3[a2[c]]

decode string

0 / 20

Complexity Analysis

For this problem, let n be the length of the input string and S be the length of the decoded output string.
What is the time complexity of this solution?
1

O(4ⁿ)

2

O(n³)

3

O(1)

4

O(S)