1. 程式人生 > 實用技巧 >力扣 - 394. 字串解碼

力扣 - 394. 字串解碼

目錄

題目

  • 給定一個經過編碼的字串,返回它解碼後的字串。
  • 編碼規則為: k[encoded_string],表示其中方括號內部的 encoded_string 正好重複 k 次。注意 k 保證為正整數。
  • 你可以認為輸入字串總是有效的;輸入字串中沒有額外的空格,且輸入的方括號總是符合格式要求的。
  • 此外,你可以認為原始資料不包含數字,所有的數字只表示重複的次數 k ,例如不會出現像 3a 或 2[4] 的輸入。

示例 1:

輸入:s = "3[a]2[bc]"
輸出:"aaabcbc"

示例 2:

輸入:s = "3[a2[c]]"
輸出:"accaccacc"

示例 3:

輸入:s = "2[abc]3[cd]ef"
輸出:"abcabccdcdcdef"

示例 4:

輸入:s = "abc3[cd]xyz"
輸出:"abccdcdcdxyz"

思路

  • 建立兩個棧進行解題,一個用來存放數字,另一個用來臨時存放子字串
  • 由於可能會在 [] 中還包含其他的 [] ,所以我們只要遇到 [ 就先將其前面的字串暫時入棧,稍後再進行計算
  • 如果遇到 ] ,則將存放數字的棧和存放子字串的棧分別出棧一個,然後進行字串的拼接,然後再將該字串作為答案的一部分進行下一輪迭代計算

程式碼實現

import java.util.LinkedList;
class Solution {
    public String decodeString(String s) {
        
        LinkedList<Integer> times = new LinkedList<>();
        LinkedList<String> preStrings = new LinkedList<>();
        String res = "";
        int time = 0;

        for (char c : s.toCharArray()) {
            // 如果為數字,則記錄數字,要注意區分各個位,不能直接相加
            if (isNum(c)) {
                time = time * 10 + Integer.parseInt(c + "");
            } else if (c == '[') { // 如果為左括號,則講數字和當前的res進棧
                times.push(time);
                preStrings.push(res);
                // 注意還要將res置空,因為要開始下一輪的字串統計,上一輪的字串已經先暫存到棧中去了
                res = "";
                // 次數也要置為0
                time = 0;
            } else if (c == ']') { // 如果為右括號,則要開始計算本次統計的res,新增到上一個字串的末尾
                // 獲取次數
                int t = times.pop();
                String curString = preStrings.pop();
                while (t > 0) {
                    curString += res;
                    t--;
                }
                // 將拼接好後的字串作為結果進行下一輪迭代
                res = curString;
                time = 0;
            } else {
                // 如果都是字母的話僅進行平解字串即可
                res += c;
            }
        }
        return res;
    }

    private boolean isNum(char c) {
        // 判斷字元是否為數字
        return c >= '0' && c <= '9';
    }
}

複雜度分析

  • 時間複雜度:\(O(N)\),N為字串的長度
  • 空間複雜度:\(O(N)\),N為字串的長度