Leetcode394. 字符串解码

Every day a Leetcode

题目来源:394. 字符串解码

解法1:栈

本题中可能出现括号嵌套的情况,比如 2[a2[bc]],这种情况下我们可以先转化成 2[abcbc],在转化成 abcbcabcbc。我们可以把字母、数字和括号看成是独立的 TOKEN,并用栈来维护这些 TOKEN。

具体的做法是,初始化一个栈 stk = stack,遍历字符串 s,设当前字符为 cur = s[i]:

  • 如果 cur 是一个数字字符:设置一个字符串 num,从当前下标 i 开始,一直遍历下去直到 i 不是数字字符,不断加入 num 中。最后将 num 压入栈中。
  • 如果 cur 是一个英文字母:将该字符转换成字符串后压入栈中。
  • 如果 cur 是 ‘[’:将该字符转换成字符串后压入栈中。
  • 否则,cur 是 ‘]’:新建一个字符串数组 sub,不断将栈顶元素弹出直到栈顶元素是 “[”,并插入到 sub 数组里。此时栈顶元素是 “[”,这个没有用,弹出,然后新的栈顶就是一个数字字符串 num,转为 int,这个就是要重复的次数,记为 repeatTime,再将栈顶弹出。由于栈的特性,数组 sub 中字符的顺序是倒置的,我们先 reverse(sub.begin(), sub.end()),再用字符串 temp 将 sub 中的字符串累加起来,最后将 temp 重复 repeatTime 次,最终得到的字符串压入栈顶。

最后,将栈中的所有字符串累加起来,再次由于栈的特性,逆序才是正确答案。我们也可以用 insert 来将栈顶字符串插入到答案的开头来做:

string ans = "";
while (!stk.empty())
{
	ans.insert(0, stk.top());
	stk.pop();
}
return ans;

代码:

/*
 * @lc app=leetcode.cn id=394 lang=cpp
 *
 * [394] 字符串解码
 */

// @lc code=start
class Solution
{
public:
    string decodeString(string s)
    {
        int n = s.size(), i = 0;
        stack<string> stk;
        while (i < n)
        {
            char cur = s[i];
            if (isdigit(cur))
            {
                string num = "";
                while (isdigit(s[i]))
                {
                    num.push_back(s[i]);
                    i++;
                }
                stk.push(num);
            }
            else if (isalpha(cur) || cur == '[')
            {
                stk.push(string(1, s[i]));
                i++;
            }
            else // cur == ']'
            {
                vector<string> sub;
                while (stk.top() != "[")
                {
                    sub.push_back(stk.top());
                    stk.pop();
                }
                reverse(sub.begin(), sub.end());
                stk.pop(); // 左括号出栈
                // 此时栈顶为当前 sub 对应的字符串应该出现的次数
                int repeatTime = stoi(stk.top());
                stk.pop();
                string temp = "";
                while (repeatTime--)
                {
                    for (string &str : sub)
                        temp += str;
                }
                stk.push(temp);
                i++;
            }
        }
        string ans = "";
        while (!stk.empty())
        {
            ans.insert(0, stk.top());
            stk.pop();
        }
        return ans;
    }
};
// @lc code=end

结果:

Leetcode394. 字符串解码_第1张图片

复杂度分析:

时间复杂度:O(S),其中 S 是解码后得出的字符串长度。除了遍历一次原字符串 s,我们还需要将解码后的字符串中的每个字符都入栈,并最终拼接进答案中,故渐进时间复杂度为 O(S+∣s∣),即 O(S)。

空间复杂度:O(S),其中 S 是解码后得出的字符串长度。这里用栈维护 TOKEN,栈的总大小最终与 S 相同。

你可能感兴趣的:(Every,day,a,LeetCode,C++,数据结构与算法,栈,模拟)