[Leetcode]394.字符串解碼

題目與解釋

給定一個通過編碼的字符串,返回它解碼後的字符串。優化

編碼規則爲: k[encoded_string],表示其中方括號內部的 encoded_string 正好重複 k 次。注意 k 保證爲正整數。this

你能夠認爲輸入字符串老是有效的;輸入字符串中沒有額外的空格,且輸入的方括號老是符合格式要求的。編碼

此外,你能夠認爲原始數據不包含數字,全部的數字只表示重複的次數 k ,例如不會出現像 3a2[4] 的輸入。code

示例:blog

s = "3[a![](https://img2018.cnblogs.com/blog/1575923/201903/1575923-20190304151000879-833294601.png)

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

解釋:遞歸

這道其實是一道字符串與棧結合的問題。如何看出是棧結合的問題呢?字符串

  1. 有匹配('['和']')的狀況,須要使用棧來完成匹配過程
  2. 有遞歸的狀況, 如3[2[ab]]這樣

在匹配符號上,我參照我以前寫的小型計算器的符號匹配,遇到']'就去尋找最近出現的匹配符號'['。string

思路

創建一個字符棧,這裏用的是STL自帶的stack<char>it

逐個讀入字符壓入棧,當遇到']'符號就尋找最近的匹配符號。io

這個尋找的過程就是不斷判斷棧頂是否爲'['符號?

->否。這個是括號內的字符,暫時存入一個字符串ss

->是。則尋找到匹配的字符,繼續往前尋找'['的字符前的全部"數字字符串",如34[22[ss]],那麼22就是[ss]的數字字符串,34則是[22[ss]]的數字字符串。在尋找完後須要將這個字符串轉換成實際的數字。

通過一次上述過程後,已經知道一個括號內字符串和這段字符串出現的次數k。咱們把k個字符串壓入咱們建立的字符棧。

而當全部字符都讀完了,則轉換實際上就已經結束了。咱們先根據思路寫一段解法,但效率還不是很高。
咱們看看"3[a1[b]]"的圖例

class Solution {
public:
    string decodeString(string s) {
        string ans = "";
        stack<char>st;
        /*visit all the character in the string s*/
        for (unsigned i = 0; i < s.length(); i++) {
            if (s[i] != ']')st.push(s[i]);
            else {
                 /*
                 if we find the character ']', it means we find a pair.
                 string ss means the string in the pair of this times.
                 string num means the number k in the pair of this times.
                 Initialize these two strings as an empty string.
                 */
                string ss = "", num = "";
                while (st.top() != '[') {
                    ss += st.top();
                    st.pop();
                }
                 /*Delete '[' character*/
                st.pop();
                 /*reverse the string ss*/
                reverse(ss.begin(), ss.end());
                while (!st.empty() && st.top() <= '9'&&st.top() >= '0') {
                    num += st.top();
                    st.pop();
                }
                unsigned times = 0, index = 1;
                for (unsigned i = 0; i < num.length(); i++, index =index* 10) {
                    times += index * (num[i]-'0');
                }
                string sss ="";
                for (unsigned i = 0; i < times; i++) {
                    sss += ss;
                }
                for (unsigned i = 0; i < sss.length(); i++) {
                    st.push(sss[i]);
                }
            }
        }
        /* push the k times string to the stack st*/
        while (!st.empty()) {
            ans += st.top();
            st.pop();
        }
        reverse(ans.begin(), ans.end());
        return ans;
    }
};

很暴力的按照思路的過程寫了代碼,優化點是能夠本身寫一個stack而不是使用STL的stack,使這個本身寫的stack擁有遍歷的方法。新增的內容有註釋提示。能將上面代碼優化4ms。

/*********added below*********/
class Stack {
public:
    Stack() {
        topNum = -1;
        ll.clear();
    }
    void push(char c) {
        ll.push_back(c);
        topNum++;
    }
    char top() {
        return ll[topNum];
    }
    void pop() {
        ll.pop_back();
        topNum--;
    }
    bool empty() {
        return topNum == -1;
    }
    vector<char>ll;
private:
    int topNum;
};
/******add above*********/
class Solution {
public:
    string decodeString(string s) {
        string ans = "";
        Stack* st=new Stack();
        for (unsigned i = 0; i < s.length(); i++) {
            if (s[i] != ']')st->push(s[i]);
            else {
                string ss = "", num = "";
                while (st->top() != '[') {
                    ss += st->top();
                    st->pop();
                }
                st->pop();
                /*Delete '[' character*/
                reverse(ss.begin(), ss.end());
                while (!st->empty() && st->top() <= '9'&&st->top() >= '0') {
                    num += st->top();
                    st->pop();
                }
                unsigned times = 0, index = 1;
                for (unsigned i = 0; i < num.length(); i++, index =index* 10) {
                    times += index * (num[i]-'0');
                }
                string sss ="";
                for (unsigned i = 0; i < times; i++) {
                    sss += ss;
                }
                for (unsigned i = 0; i < sss.length(); i++) {
                    st->push(sss[i]);
                }
            }
        }
        /******change below********/
        for (char it : st->ll) {
            ans += it;
        }
        /******change above********/
        delete st;
        return ans;
    }
};
相關文章
相關標籤/搜索