HomeLeetcode394. Decode String - Leetcode Solutions

394. Decode String – Leetcode Solutions

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 105.

Examples:

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"

Solution in Python

Key Concepts

  1. Stack-Based Decoding:
    • Use a stack to store intermediate results and handle nested encoded substrings.
    • Push the current string and repetition count onto the stack when encountering an opening bracket [.
    • When encountering a closing bracket ], pop the stack, repeat the substring accordingly, and append it to the result.
  2. Iterative Parsing:
    • Parse the string character by character.
    • Maintain separate variables to track the current repetition count and the current working string.
Python
class Solution:
    def decodeString(self, s: str) -> str:
        # Stack to hold (current string, repetition count)
        stack = []
        # Current working string
        current_string = ""
        # Current repetition count
        current_number = 0

        for char in s:
            if char.isdigit():
                # Build the current number (handles multi-digit numbers)
                current_number = current_number * 10 + int(char)
            elif char == '[':
                # Push the current string and number to the stack
                stack.append((current_string, current_number))
                # Reset current string and number for the next scope
                current_string = ""
                current_number = 0
            elif char == ']':
                # Pop from the stack, repeat the current string, and append to previous string
                prev_string, repeat_count = stack.pop()
                current_string = prev_string + (current_string * repeat_count)
            else:
                # Append the current character to the working string
                current_string += char

        return current_string

Explanation of the Code

  1. Initialization:
    • stack: Stores tuples of the previous string and repetition count before entering a nested encoded substring.
    • current_string: Tracks the substring currently being constructed.
    • current_number: Tracks the repetition count for the current substring.
  2. Parsing the String:
    • Digits: Build current_number by multiplying the previous value by 10 and adding the digit (handles multi-digit numbers).
    • Opening Bracket ([):
      • Push the current string and repetition count onto the stack.
      • Reset current_string and current_number for the new scope.
    • Closing Bracket (]):
      • Pop the stack to retrieve the previous string and repetition count.
      • Repeat current_string repeat_count times and append it to the prev_string.
    • Characters: Append to current_string to build the substring.
  3. Return the Result:
    • After processing the input, current_string contains the fully decoded string.

Solution in C++

C++
class Solution {
public:
    string decodeString(string s) {
        // Stack to store previous string states and repeat counts
        stack<string> strStack;
        stack<int> countStack;
        
        // Current decoded string
        string currentStr = "";
        
        // Variable to hold the current multiplier value
        int currentNum = 0;

        // Iterate over the input string character by character
        for (char c : s) {
            if (isdigit(c)) {
                // Build the current multiplier (k)
                currentNum = currentNum * 10 + (c - '0');
            } else if (c == '[') {
                // Push the current state into stacks and reset
                countStack.push(currentNum);
                strStack.push(currentStr);

                // Reset current state
                currentNum = 0;
                currentStr = "";
            } else if (c == ']') {
                // Pop the last state from stacks
                int repeatCount = countStack.top(); countStack.pop();
                string prevStr = strStack.top(); strStack.pop();

                // Append the repeated string to the previous string
                string decoded = "";
                for (int i = 0; i < repeatCount; ++i) {
                    decoded += currentStr;
                }

                // Update current string with the combined result
                currentStr = prevStr + decoded;
            } else {
                // Append regular characters to the current string
                currentStr += c;
            }
        }

        // Return the fully decoded string
        return currentStr;
    }
};

Solution in Javascript

JavaScript
var decodeString = function(s) {
    // Initialize a stack to hold characters and numbers during processing.
    let stack = [];
    
    // Iterate through each character in the string.
    for (let char of s) {
        if (char !== ']') {
            // If the character is not a closing bracket, push it onto the stack.
            stack.push(char);
        } else {
            // If the character is a closing bracket, process the stack to decode the segment.

            // Step 1: Build the encoded substring inside the brackets.
            let substring = '';
            while (stack.length && stack[stack.length - 1] !== '[') {
                substring = stack.pop() + substring;
            }
            
            // Remove the opening bracket '['.
            stack.pop();

            // Step 2: Get the number (k) associated with this substring.
            let k = '';
            while (stack.length && /\d/.test(stack[stack.length - 1])) {
                k = stack.pop() + k;
            }
            k = parseInt(k);

            // Step 3: Expand the substring k times and push it back onto the stack.
            stack.push(substring.repeat(k));
        }
    }

    // Join the stack to form the final decoded string.
    return stack.join('');
};

Solution in Java

Java
class Solution {
    public String decodeString(String s) {
        // Stack to hold the count of repetitions for each nested segment
        Stack<Integer> countStack = new Stack<>();
        // Stack to hold the result of previous segments
        Stack<StringBuilder> resultStack = new Stack<>();
        // StringBuilder to construct the current segment
        StringBuilder current = new StringBuilder();
        int k = 0; // To track the current multiplier
        
        for (char ch : s.toCharArray()) {
            if (Character.isDigit(ch)) {
                // If the character is a digit, update the multiplier (k)
                k = k * 10 + (ch - '0');
            } else if (ch == '[') {
                // Push the multiplier and current segment to their respective stacks
                countStack.push(k);
                resultStack.push(current);
                // Reset for the next segment
                k = 0;
                current = new StringBuilder();
            } else if (ch == ']') {
                // End of the current nested segment
                // Pop the multiplier and the previous segment from the stacks
                int repeatCount = countStack.pop();
                StringBuilder previous = resultStack.pop();
                // Repeat the current segment and append it to the previous segment
                for (int i = 0; i < repeatCount; i++) {
                    previous.append(current);
                }
                // Update the current segment with the combined result
                current = previous;
            } else {
                // Append regular characters to the current segment
                current.append(ch);
            }
        }
        // Return the final decoded string
        return current.toString();
    }
}

Subscribe
Notify of

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Popular