LeetCode/solutions/394. Decode String.md
2020-01-01 21:25:24 +08:00

50 lines
2.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# [394. Decode String](https://leetcode.com/problems/decode-string/)
# 思路
给定一个编码后的字符串,根据规则对其解码。
由题意知,由于`k[encoded_string]`中的`encoded_string`内部依然可能包含`k[encoded_string]`这种形式,所以我们可以用递归求解。
我们用res表示当前已经解码好的字符串用两个指针`l`和`r`分别代表子串的左右边界,然后用`brackets_count`表示待配对的括号数,则有以下几种情况:
1. 如果`s[r] >= '0' && s[r] <= '9' && brackets_count == 0`: 说明此时`s.substr(l, r-l)`是一个普通的串,无需解码,
即`res += s.substr(l, r-l)`即可。由于此时`s[r]`是数字即一个数的开头所以我们还需用一个变量k记录这个数留在下次用。
2. 否则,如果`s[r] == '['`,待配对的括号数加一个,即`brackets_count++`。
3. 否则,如果`s[r] == ']'`,待配对的括号数减一个,即`brackets_count--`。另外如果此时`brackets_count`等于0了
说明此时`s.substr(l, r-l)`就是一个需要递归调用解码函数的子串而且别忘了次数k所以`res`加`k`次`decodeString(s.substr(l, r-l))`即可。
4. 否则,即普通字符,那么`r++`即可(注意上述三种情况最后也需要合理更新`l`和`r`)。
此题也可以用迭代的解法用两个stack一个记录次数k一个记录待处理子串。
# C++
``` C++
class Solution {
public:
string decodeString(string s) {
if(s.size() == 0) return "";
string res = "";
int l = 0, r = 0;
int brackets_count = 0, k = -1;
while(r < s.size()){
if(s[r] >= '0' && s[r] <= '9' && !brackets_count){
res += s.substr(l, r-l);
l = r;
while(r < s.size() && s[r] >= '0' && s[r] <= '9') r++;
k = stoi(s.substr(l, r-l));
l = r + 1;
r -= 1; // 后面要加1所以这里先减去1
}
else if(s[r] == '[') brackets_count++;
else if(s[r] == ']'){
if(--brackets_count == 0){
while(k--)
res += decodeString(s.substr(l, r-l));
l = r + 1;
}
}
r++;
}
return res + s.substr(l, r-l);
}
};
```