LeetCode 394. Decode String

Recursive

递归处理字符串的题,思路很简单,如果遇到数字,把数字找出来,后面必然是'[',然后 res += decodeString(括号里的内容)。

但是括号内的内容很难直接找到,如果用 while(s[i]!=']') 来找,一旦遇到括号嵌套就会出错。因此,可以把括号的处理放入递归内做。另外注意引用传递在本题的应用。

class Solution {
public:
    string decodeString(string s){
        int index=0;
        return decodeString(s,index);
    }
    
    string decodeString(string s, int &i) {
        string res="";
        while (i<s.size() && s[i]!=']'){
            if (!isdigit(s[i])) res+=s[i++];
            else{
                int num=0;
                while (i<s.size()&&isdigit(s[i])){
                    num = num*10+s[i]-'0';
                    ++i;
                }
                ++i; //skip [
                string tmp=decodeString(s,i);
                for(int j=0;j<num;++j) res+=tmp;
                ++i; //skip ]
            }
        }
        return res;
    }
};

 

Another Approach

for循环,然后对于不同的当前字符分别做不同的处理。

1. 如果是数字,读取连续的所有数字并转换为int。

2. 如果是字母,直接加到res。

3. 如果是'[',递归开始,返回的string就是[]里的内容,然后重复num次加到res里。

4. 如果是']',说明递归结束,返回res。

这种方法本质和上面一种方法是一样的,上面方法的while循环其实包括了遇到']'终止然后return的情况,比较巧妙。这种写法不容易出错。

class Solution {
public:
    string decodeString(string s) {
        int index=0;
        return decodeString(s,index);
    }
    
    string decodeString(string s, int &i){
        string res="";
        int num;
        for (;i<s.size();++i){
            char ch=s[i];
            if (isdigit(ch)){
                num = 0;
                while (i<s.size() && isdigit(s[i]))
                    num = num*10 + (s[i++]-'0');
                --i;
            }else if (ch=='['){
                string tmp=decodeString(s,++i);
                for (int k=0;k<num;++k) res+=tmp;
            }else if (ch==']'){
                return res;
            }else{ // Normal characters
                res += ch;
            }
        }
        return res;
    }
};

 

Stack 

stack写法就和 Basic Calculator 极其相似了。Basic Calculator 那题也可以用上面的递归写法。

class Solution {
public:
    string decodeString(string s) {
        string res="";
        int num=0;
        stack<string> resStack;
        stack<int> cntStack;
        
        for (int i=0;i<s.size();++i){
            char ch=s[i];
            if (isdigit(ch)){
                num = 0;
                while (i<s.size() && isdigit(s[i]))
                    num = num*10 + (s[i++]-'0');
                --i;
            }else if (isalpha(ch)){
                res += ch;
            }else if (ch=='['){
                resStack.push(res);
                cntStack.push(num);
                res = "";
                num = 0;
            }else if (ch==']'){
                int cnt=cntStack.top(); cntStack.pop();
                string new_res=resStack.top(); resStack.pop();
                for (int k=0;k<cnt;++k) new_res+=res;
                res = new_res;
            }
        }
        return res;
    }
};

 

Reference

https://leetcode.com/problems/decode-string/discuss/87544/Clean-C++-Recursive-Solution-with-Explanation

https://leetcode.com/problems/decode-string/discuss/87561/Concise-Java-Solution-with-stack

posted @ 2018-07-19 15:35  約束の空  阅读(124)  评论(0)    收藏  举报