Given an encoded string, return its 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; there are 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 will not be input like 3a
or 2[4]
.
The test cases are generated so that the length of the output will never exceed 10^5
.
題目摘要
k[encoded_string]
(表示 encoded_string
需要重複 k
次),回傳處理後的字串。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"
解題思路
[
時,我們可以將前面的數字和字串分別存入堆疊中;當遇到 ]
時,則從堆疊中取出相應的部分進行重複和拼湊。[
時,將目前的數字和字串存入堆疊,準備處理內部的子字串。]
時,從堆疊中取出上次存入的數字和字串,將當前的子字串重複多次,並和之前的部分拼接。程式碼
class Solution {
public String decodeString(String s) {
//定義兩個堆疊:一個用來存字串,另一個用來存重複次數k
Stack<String> stringStack = new Stack<>();
Stack<Integer> kStack = new Stack<>();
//用StringBuilder來累積當前字串:提高效能固非使用String
StringBuilder p = new StringBuilder();
int k = 0;
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i); //取出當前字元
//如果是數字,累積當前的重複次數k
if (Character.isDigit(ch)) {
//將數字字元轉換為整數,並累積形成完整的數字
k = k * 10 + (ch - '0');
}
//如果遇到左括號 '[', 開始新的子字串
else if (ch == '[') {
//將當前的重複次數k和已經處理的字串p加入堆疊
kStack.push(k);
stringStack.push(p.toString());
//重置當前字串為空,準備處理新的子字串
p = new StringBuilder();
k = 0; //重置k為0,準備下一次的數字累積
}
//如果遇到右括號 ']', 表示一個完整的子字串結束
else if (ch == ']') {
//從堆疊中取出對應的重複次數和字串
int repeatTimes = kStack.pop();
StringBuilder temp = new StringBuilder(stringStack.pop());
//將當前的字串p重複repeatTimes次,並加到temp中
for (int j = 0; j < repeatTimes; j++) {
temp.append(p);
}
//更新當前字串p為重複拼湊後的結果
p = temp;
}
//如果是字母,直接將其加入到當前字串p中
else {
p.append(ch);
}
}
//最後回傳完整字串
return p.toString();
}
}
結論: 在寫這題前我先觀看了leetcode上許多網友對於這題給出的程式碼,一開始看到對於p
這個用來存放累積子字串使用方法為StringBuilder()
而非string
的變數型態感到很疑惑。一查之後才發現,相較於使用string
,使用StringBuilder()
允許在不創建新物件的情況下修改同一個字串內容。每次 append()
操作只是在原始字串的基礎上添加新內容,其效率會比string
做拼湊要高得多。果然,即使身為正在學習資訊科系的我,也仍然有無窮無盡的茫茫程式海需要去學習、多看、多聽!