LeetCode: Decode String

https://leetcode.com/problems/decode-string/, this problem looked much simpler than it actually was. Code wise it was not that complicated, but it turned out being a fairly "special case" code with many different conditions being handled. It was neither a linear straightforward string manipulation solution, nor a base-case-induction stack-based one. It was a hybrid, which made the code hard to follow IMO.

Here is the problem:

Given an encoded string, return it's 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; 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 won't be input like 3a or 2[4].
Examples:
s = "3[a]2[bc]", return "aaabcbc".
s = "3[a2[c]]", return "accaccacc".
s = "2[abc]3[cd]ef", return "abcabccdcdcdef".

The approach will be a recursive one, similar to a math expression evaluate code, but with some basic string manipulation along the way. As you can see in the code down below it does become hard to quite follow with the few too many special cases. Slightly better than 50% of the other submissions. Cheers, Marcelo.


    public class Solution
    {
        public string DecodeString(string s)
        {
            //Base case
            if (String.IsNullOrEmpty(s)) return s;

            //Case when the string has no numbers
            string retVal = "";
            int index = 0;
            while (index < s.Length && s[index] >= 'a' && s[index] <= 'z')
                retVal += s[index++].ToString();

            //Case when the string has a multiplying factor
            int factor = 0;
            while (index < s.Length && s[index] >= '0' && s[index] <= '9')
                factor = 10 * factor + (int)(s[index++] - '0');

            if (factor > 0)
            {
                //For the brackets, need to handle the nested ones
                int nOpen = 1;
                index++;
                int beginIndex = index;
                while (nOpen > 0)
                {
                    if (s[index] == '[') nOpen++;
                    if (s[index] == ']') nOpen--;
                    if (nOpen > 0) index++;
                }

                //Call recursively for the brackets
                string temp = s.Substring(beginIndex, index - beginIndex);
                string subRetVal = DecodeString(temp);

                //The multiplying factor
                for (int i = 0; i < factor; i++)
                    retVal += subRetVal;

                //Now remember that the string may continue, in which case another recursive call is needed
                if (index + 1 < s.Length)
                    retVal += DecodeString(s.Substring(index + 1));
            }

            //Finally, the return
            return retVal;
        }
    }

Comments

  1. It's a good one for testing stack understanding - checking if parenthesis are balanced is passé :) In general I try to avoid using implicit stack via recursion, since it can potentially overflow and is usually more expensive in terms of CPU and memory. Here is my dumb 0ms C++ solution:

    class Solution {
    public:
    string decodeString(const string& str) {
    stack s;
    s.push("");
    stack reps;
    int k = 0;
    for (char ch : str) {
    if (isdigit(ch)) {
    k = k*10 + (ch-'0');
    } else if (ch == '[') {
    reps.push(k);
    s.push("");
    k = 0;
    } else if (ch == ']') {
    string expanded;
    for (int i = 0; i < reps.top(); ++i) expanded.append(s.top());
    reps.pop();
    s.pop();
    s.top().append(expanded);
    } else {
    s.top().append(1, ch);
    }
    }
    return s.top();
    }
    };

    ReplyDelete

Post a Comment

Popular posts from this blog

Golang vs. C#: performance characteristics (simple case study)

Claude vs ChatGPT: A Coder's Perspective on LLM Performance

ProjectEuler Problem 719 (some hints, but no spoilers)