[LeetCode] 394. Decode String 解碼字符串


 

Given an encoded string, return it's decoded string.

The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is 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 like 3a or 2[4].

Examples:

s = "3[a]2[bc]", return "aaabcbc".
s = "3[a2[c]]", return "accaccacc".
s = "2[abc]3[cd]ef", return "abcabccdcdcdef".

 

這道題讓我們把一個按一定規則編碼后的字符串解碼成其原來的模樣,編碼的方法很簡單,就是把重復的字符串放在一個括號里,把重復的次數放在括號的前面,注意括號里面有可能會嵌套括號,這題可以用遞歸和迭代兩種方法來解,我們首先來看遞歸的解法,把一個括號中的所有內容看做一個整體,一次遞歸函數返回一對括號中解碼后的字符串。給定的編碼字符串實際上只有四種字符,數字,字母,左括號,和右括號。那么我們開始用一個變量i從0開始遍歷到字符串的末尾,由於左括號都是跟在數字后面,所以首先遇到的字符只能是數字或者字母,如果是字母,直接存入結果中,如果是數字,循環讀入所有的數字,並正確轉換,那么下一位非數字的字符一定是左括號,指針右移跳過左括號,對之后的內容調用遞歸函數求解,注意我們循環的停止條件是遍歷到末尾和遇到右括號,由於遞歸調用的函數返回了子括號里解碼后的字符串,而我們之前把次數也已經求出來了,那么循環添加到結果中即可,參見代碼如下:

 

解法一:

class Solution {
public:
    string decodeString(string s) {
        int i = 0;
        return decode(s, i);
    }
    string decode(string s, int& i) {
        string res = "";
        int n = s.size();
        while (i < n && s[i] != ']') {
            if (s[i] < '0' || s[i] > '9') {
                res += s[i++];
            } else {
                int cnt = 0;
                while (s[i] >= '0' && s[i] <= '9') {
                    cnt = cnt * 10 + s[i++] - '0';
                }
                ++i;
                string t = decode(s, i);
                ++i;
                while (cnt-- > 0) {
                    res += t;
                }
            }
        }
        return res;
    }
};

 

我們也可以用迭代的方法寫出來,當然需要用 stack 來輔助運算,我們用兩個 stack,一個用來保存個數,一個用來保存字符串,我們遍歷輸入字符串,如果遇到數字,我們更新計數變量 cnt;如果遇到左括號,我們把當前 cnt 壓入數字棧中,把當前t壓入字符串棧中;如果遇到右括號時,我們取出數字棧中頂元素,存入變量k,然后給字符串棧的頂元素循環加上k個t字符串,然后取出頂元素存入字符串t中;如果遇到字母,我們直接加入字符串t中即可,參見代碼如下:

 

解法二:

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();
    }
};

 

類似題目:

Encode String with Shortest Length

Number of Atoms

 

參考資料:

https://leetcode.com/problems/decode-string/

https://leetcode.com/problems/decode-string/discuss/87728/share-my-c-solution

https://leetcode.com/problems/decode-string/discuss/87543/0ms-simple-C%2B%2B-solution

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM