《LeetCode之每日一题》:115.字符串解码

Posted 是七喜呀!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:115.字符串解码相关的知识,希望对你有一定的参考价值。

字符串解码


题目链接: 字符串解码

有关题目

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],
表示其中方括号内部的 encoded_string 正好重复 k 次。
注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,
且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,
所有的数字只表示重复的次数 k ,
例如不会出现像 3a 或 2[4] 的输入。
示例 1:

输入:s = "3[a]2[bc]"
输出:"aaabcbc"
示例 2:

输入:s = "3[a2[c]]"
输出:"accaccacc"
示例 3:

输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"
示例 4:

输入:s = "abc3[cd]xyz"
输出:"abccdcdcdxyz"

题解

法一:栈操作

class Solution {
public:
    string getDigits(string &s, size_t &ptr){
        string ret = "";
        while(isdigit(s[ptr])){
            ret += s[ptr++];
        }
        return ret;
    }

    string getString(vector<string> &v){
        string rec = "";
        for (const auto& s : v){
            rec += s;
        }
        return rec;
    }
    string decodeString(string s) {
        vector<string> stk;
        size_t ptr = 0;

        while(ptr < s.size()){
            char cur = s[ptr];
            if (isdigit(cur)){
                string digits = getDigits(s, ptr);
                stk.push_back(digits);
            } else if (isalpha(cur) || cur == '['){
            //string(num, c)生成num个c字符的字符串
                stk.push_back(string(1, s[ptr++]));
            } else {//']'
                ptr++;

                vector<string> sub;//存放当前子串

                while(stk.back() != "["){//stk.back()
                    sub.push_back(stk.back());
                    stk.pop_back();
                }
                
                reverse(sub.begin(), sub.end());//恢复原序
        
                //过滤左括号
                stk.pop_back();

                // 此时栈顶为当前 sub 对应的字符串应该出现的次数
                int repTimes = stoi(stk.back());

                //除去数字
                stk.pop_back();
                string t, o = getString(sub);

                while(repTimes--) t += o;
                
                //将构造好的字符串入栈
                stk.push_back(t);
            }
        }
        return getString(stk);
    }
};

代码二:

class Solution {
public:
    string decodeString(string s) {
        string res = ""; int num = 0;
        stack<int> nums;
        stack<string> strs;
        int len = s.size();

        for (int i = 0; i < len; i++){
            if (s[i] >= '0' && s[i] <= '9'){
                num = num * 10 + s[i] - '0';
            } else if ((s[i] >= 'A' && s[i] <= 'Z') || (s[i] >= 'a' && s[i] <= 'z')){
                    res += s[i];
            } else if (s[i] == '[') {//将‘[’前的数字压入nums栈内, 字母字符串压入strs栈内
                nums.push(num);
                num = 0;
                strs.push(res);
                res = "";//这边以3[a2[bc]]为例;
            } else {//遇到‘]’时,操作与之相配的‘[’之间的字符,
                int repTimes = nums.top();
                nums.pop();
                
                for (int i = 0; i < repTimes; i++){
                    strs.top() += res;
                }
                res = strs.top();//之后若还是字母,就会直接加到res之后,因为它们是同一级的运算
                                  //若是左括号,res会被压入strs栈,作为上一层的运算
                strs.pop();
            }
        }
        return res;
    }
};


法二:递归

class Solution {
public:
    string src;
    size_t ptr;
    int getDigits(){
        int res = 0;
        while(isdigit(src[ptr])){
            res = res * 10 + src[ptr++] - '0';
        }
        return res;
    }
    string getString(){
        //递归终止条件
        if (ptr == src.size() || src[ptr] == ']'){
            return "";
        }
        
        char cur = src[ptr]; int repTimes = 1;
        string ret = "";

        if (isdigit(cur)){
            repTimes = getDigits();

            //过滤左括号
            ptr++;
            
            string str = getString();

            //过滤右括号
            ptr++;

            // 构造字符串
            while(repTimes--) ret += str;
            
        } else if (isalpha(cur)){
            ret = string(1, src[ptr++]);
        }
        return ret + getString();
    }
    string decodeString(string s) {
        src = s;
        ptr = 0;
        return getString();
    }
};

以上是关于《LeetCode之每日一题》:115.字符串解码的主要内容,如果未能解决你的问题,请参考以下文章

《LeetCode之每日一题》:22. 解码异或后的数组

每日一题剑指 Offer II 115. 重建序列

LeetCode每日一题(1734. 解码异或后的排列)

LeetCode每日一题(1720. 解码异或后的数组)

《LeetCode之每日一题》:224.连续字符

《LeetCode之每日一题》:123.字符串相乘