LeetCode - 394. 字符串解码

题目

394. 字符串解码 - 力扣(LeetCode)

思路

这道字符串解码题目,我看完后的第一反应是需要处理嵌套的编码规则,很适合用栈或者递归来解决。我倾向于用栈,因为它更直观一些。

我的思路是这样的:

  1. 从左到右遍历字符串
  2. 用一个栈来处理嵌套结构
  3. 遇到数字时,记录下来作为重复次数
  4. 遇到'['时,把当前已经解析的字符串和重复次数压入栈,然后重置当前字符串和重复次数
  5. 遇到']'时,从栈中弹出重复次数和之前的字符串,将当前字符串重复对应次数后,拼接到之前的字符串后面
  6. 遇到字母时,直接添加到当前字符串中

举个例子,以"3[a]2[bc]"为例:

  • 遇到'3',记录重复次数为3
  • 遇到'[',将当前字符串""和重复次数3压入栈,重置当前字符串和重复次数
  • 遇到'a',将其添加到当前字符串,当前字符串变为"a"
  • 遇到']',弹出栈顶的重复次数3和之前的字符串"",将当前字符串"a"重复3次得到"aaa",拼接到之前的字符串后面,当前字符串变为"aaa"
  • 遇到'2',记录重复次数为2
  • 遇到'[',将当前字符串"aaa"和重复次数2压入栈,重置当前字符串和重复次数
  • 遇到'b',将其添加到当前字符串,当前字符串变为"b"
  • 遇到'c',将其添加到当前字符串,当前字符串变为"bc"
  • 遇到']',弹出栈顶的重复次数2和之前的字符串"aaa",将当前字符串"bc"重复2次得到"bcbc",拼接到之前的字符串后面,当前字符串变为"aaabcbc"
  • 遍历结束,返回当前字符串"aaabcbc"

这种方法能够处理嵌套的情况,比如示例2中的"3[a2[c]]",因为每次遇到'['时都会将当前状态压入栈,遇到']'时再弹出并处理。

时间复杂度是O(n),其中n是解码后字符串的长度,因为每个字符最多被处理一次。空间复杂度是O(m),其中m是编码字符串的长度,主要是栈的空间。

在实际编码时,我需要注意几个细节:数字可能是多位的,需要连续读取

正确写法

cpp 复制代码
class Solution {
public:
    string decodeString(string s) {
        stack<string> stStr;
        stack<int> stNum;
        int i = 0;
        stStr.push("");
        while(i<s.size())
        {
            if(s[i] >='0' && s[i] <='9')
            {
                int num = 0;
                while(s[i] >='0' && s[i] <='9')
                {
                    num = num*10 + (s[i] - '0');
                    i++;
                }
                stNum.push(num);
            }
            else if(s[i] == '[')
            {
                i++;
                string str;
                while(s[i] >= 'a' && s[i] <= 'z')
                {
                    str+=s[i];
                    i++;
                }
                stStr.push(str);
            }
            else if(s[i] == ']')
            {
                string str = stStr.top();
                stStr.pop();
                int k = stNum.top();
                stNum.pop();
                while(k--)
                {
                    stStr.top() += str;
                }
                i++;
            }
            else
            {
                string str;
                while(i < s.size()&& s[i] >= 'a' && s[i] <= 'z')
                {
                    str += s[i];
                    i++;
                }
                stStr.top() += str;
            }
        }
        return stStr.top();
    }
};