1. 程式人生 > 其它 >【leetcode】394. Decode String

【leetcode】394. Decode String

Given an encoded string, return its decoded string.

The encoding rule is:k[encoded_string], where theencoded_stringinside the square brackets is being repeated exactlyktimes. Note thatkis 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 like3aor2[4].

Example 1:

Input: s = "3[a]2[bc]"
Output: "aaabcbc"

Example 2:

Input: s = "3[a2[c]]"
Output: "accaccacc"

Example 3:

Input: s = "2[abc]3[cd]ef"
Output: "abcabccdcdcdef"

Example 4:

Input: s = "abc3[cd]xyz"
Output: "abccdcdcdxyz"

思路一:利用遞迴去做,如果遇到數字就進行展開,由於遞迴的結構就會自動從裡到外一層一層的展開返回,注意檢索的陣列index得傳引用,o(n)的時間複雜度,注意數字可能是兩位數或者三位數。 雖然oc了,但是程式碼十分不優雅。。。 看起來很碎。

class Solution {
public:
    string decodeString(string s) {
        // 用什麼樣的資料結構可以方便的完成字串的解碼呢?
        // 用一個遞迴的結構去一層一層的展開
        string res="";
        int n=s.size();
        for(int i=0;i<n;++i){
            if(s[i]>='a' && s[i]<='z'){
                res+=s[i];
            }
            else{
                res+=unfold(i,s,n);
                cout<<i<<endl;
            }
        }
        return res;
        
    }
    string unfold(int &i,string &s,int &n){
        // 將摺疊的字串展開 這個數字可能會有很多位
        int num=0;
        while(i<n){
            if(s[i]>='0'&&s[i]<='9'){
                num=num*10+(s[i]-'0');
            }
            else{
                break;
            }
            i++;
        }
        string tmp="";
        string res="";
        while(i<n){
            if(s[i]>='a' &&s[i]<='z'){
                tmp+=s[i];
            }
            else if(s[i]>='0'&&s[i]<='9'){
                tmp+=unfold(i,s,n);
            }
            else if(s[i]==']') break;
            i++;
        }
        for(int j=0;j<num;++j){
            res+=tmp;
        }
        return res;
    }
};

思路二,利用兩個堆疊進行處理。一個棧用來儲存重複字串個數 ,一個棧儲存需要重複的字串字首。

class Solution {
public:
    string decodeString(string s) {
        string t = "";
        stack<int> s_num;
        stack<string> s_str;
        int cnt = 0;
        for (int i = 0; i < s.size(); ++i) {
            if (s[i] >= '0' && s[i] <= '9') {
                cnt = 10 * cnt + s[i] - '0';
            } else if (s[i] == '[') {
                s_num.push(cnt);
                s_str.push(t);
                cnt = 0; t.clear();
            } else if (s[i] == ']') {
                int k = s_num.top(); s_num.pop();
                for (int j = 0; j < k; ++j) s_str.top() += t;
                t = s_str.top(); s_str.pop();
            } else {
                t += s[i];
            }
        }
        return s_str.empty() ? t : s_str.top();
    }
};