用棧實現leetcode第394題:字符串解碼(帶圖解)

題目描述

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

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

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

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

示例:

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

思路

藉助棧來完成。code

  1. 計算串出現的次數,即[左側的數字。
  2. 若是是字母,直接入棧
  3. 若是是[,則將計算好的次數入棧
  4. 若是是],開始彈棧字符串

    1. 若是是字母,則進行拼接s。(注意後彈棧出的元素放在前面,須要使用insert(0, ch))
    2. 若是是數字n,則將n個s進行拼接,而後入棧。並結束彈棧。

舉例

計算3[a4[bc]]的結果。string

3 [ a 4 [ b c ] ]

stack = {}
count = 3it

3 [ a 4 [ b c ] ]

stack = {3}
count = 0io

3 [ a 4 [ b c ] ]

stack = {3, a}
count = 0table

3 [ a 4 [ b c ] ]

stack = {3, a}
count = 4

3 [ a 4 [ b c ] ]

stack = {3, a, 4}
count = 0

3 [ a 4 [ b c ] ]

stack = {3, a, 4, b}
count = 0

3 [ a 4 [ b c ] ]

stack = {3, a, 4, b, c}
count = 0

3 [ a 4 [ b c ] ]

stack = {3, a, bc, bc, bc, bc}
count = 0

由於遇到 ],須要彈棧。將彈出的字符進行拼接(後出棧的拼接在字符串前面),知道遇到數字n,則將N個字符串入棧。因此須要將4個"bc"字符串入棧
3 [ a 4 [ b c ] ]

stack = {abcbcbcbc, abcbcbcbc, abcbcbcbc}
count = 0

由於遇到 ],須要彈棧。將彈出的字符進行拼接(後出棧的拼接在字符串前面),知道遇到數字n,則將N個字符串入棧。因此須要將3個"abcbcbcbc"字符串入棧

遍歷完成以後,將棧中數據拼接便可獲得最終結果:abcbcbcbcabcbcbcbcabcbcbcbc

代碼

public String decodeString(String s) {
    char[] chs = s.toCharArray();
    Stack<String> stack = new Stack<>();
    int count = 0;
    for (int i = 0, len = chs.length; i < len; i++) {
      char ch = chs[i];
      if (ch >= '0' && ch <= '9') {
        // 統計數字。eg: 12是2個字符進行處理的
        count = 10 * count + (ch - '0');
      } else if (ch == '[') {
        // 遇到[,則將數字入棧
        stack.push(String.valueOf(count));
        count = 0;
      } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
        // 字母直接入棧
        stack.push(String.valueOf(ch));
      } else if (ch == ']') {
        // 遇到],開始彈棧處理字符串解碼
        StringBuilder sb = new StringBuilder();
        while (!stack.empty()) {
          String s1 = stack.pop();
          if (isDigital(s1)) {
            int j = 0;
            while (j++ < Integer.parseInt(s1)) {
              stack.push(sb.toString());
            }
            break;
          } else {
            sb.insert(0, s1);
          }
        }
      }
    }

    StringBuilder res = new StringBuilder();
    while (!stack.empty()) {
      res.insert(0, stack.pop());
    }

    return res.toString();
}

private boolean isDigital(String s) {
    try {
        Integer.parseInt(s);
        return true;
    } catch (Exception e) {
        return false;
    }
}
相關文章
相關標籤/搜索