# LeetCode 394：字符串解码 Decode String

2019.08.13 22:59 505浏览

### 题目：

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; 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 won’t be input like `3a` or `2[4]`.

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

### 解题思路：

​ 这道题类似我们之前做过的一道题：有效的括号: https://mp.weixin.qq.com/s/Sm1S26EgR-dC75hrhVnZGQ

``````输入:'3[a2[c]]'

num暂存数字3

nums: 3		res: ''
num置为0，str置空

num暂存数字2

num入栈nums,res入栈str
nums: 3 -> 2	str: '' -> 'a'
num置为0，str置空

nums弹出栈顶元素：当前字符串重复次数2
res = res*2 = 'cc'
str弹出栈顶元素'a'与res拼接并入栈:
res = 'a'+'cc'='acc'
str: '' -> 'acc'

nums弹出栈顶元素：当前字符串重复次数3
res = res*3 = 'accaccacc'
str弹出栈顶元素空字符串''与res拼接并入栈:
res=''+'accaccacc'='accaccacc'
str: 'accaccacc'

``````

• 由于重复次数可能大于10，所以暂存数字时要适当处理，如 `num*10+当前数字`
• 在c++里可以直接修改拼接字符，但Java不支持运算符重载，可以借助 StringBuilder 或 StringBuffer 类。
• 用栈暂存的逻辑与递归基本一致，可以理解为用递归实现栈。
• python没有栈这种数据结构，可以用 list() 数组或双端队列 deque()
• python可以只用一个栈以元组的形式重复次数和字符串，如`(num,res)`

### 利用栈：

Java：

``````class Solution {
public String decodeString(String s) {
//初始化数据结构
Stack<StringBuilder> str = new Stack<>();
Stack<Integer> nums = new Stack<>();
StringBuilder res = new StringBuilder();
int num = 0;
for (char c : s.toCharArray()) {//递归字符串
if (c == '[') {
str.push(res);//入栈
nums.push(num);
num = 0;//刷新num、res
res = new StringBuilder();
} else if (c == ']') {
StringBuilder tmp = new StringBuilder();
for (int i = nums.pop(); i > 0; i--) tmp.append(res);//res*3
res = str.pop().append(tmp);
} else if (c >= '0' && c <= '9') num = num * 10 + (c - '0');//计算重复次数
else res.append(c);
}
return res.toString();
}
}
``````

Python：

• `isdigit()` 是否为只包含数字的字符串
• `isalpha()` 是否为只包含字母的字符串
``````class Solution:
def decodeString(self, s: str) -> str:
#初始化数据结构
stack, res, num = [], '', 0
for c in s:
if c.isdigit():
num = num * 10 + int(c)
elif c.isalpha():
res += c
elif c == '[':
#元组形式入栈
stack.append((res, num))
#刷新字符串和重复次数
res, num = '', 0
else:
#如果c==']',弹出字符串和重复次数
last_str, this_num = stack.pop()
res = last_str + this_num * res
return res
``````

### 利用递归：

Java：

``````class Solution {
private int i = -1;//全局变量i，记录字符数组指针位置

public String decodeString(String s) {
return dfs(s.toCharArray(), s.length()).toString();
}
//递归函数
private StringBuilder dfs(char[] chars, int len) {
int num = 0;
StringBuilder str = new StringBuilder();
while (++i < len) {
if (chars[i] >= '0' && chars[i] <= '9')
num = num * 10 + (chars[i] - '0');
else if (chars[i] == '[') {
StringBuilder tmp = dfs(chars, len);//递归调用
while (--num >= 0) str.append(tmp);//重复字符串res=res*num
num = 0;
} else if (chars[i] == ']') return str;
else str.append(chars[i]);
}
return str;
}
}
``````

Python：

``````class Solution:
i = -1
#递归函数，可以直接操作字符串就无需再建一个dfs辅助函数
def decodeString(self, s: str) -> str:
res, num = '', 0
while self.i < len(s) - 1:
self.i += 1
if s[self.i].isdigit():
num = num * 10 + int(s[self.i])
elif s[self.i].isalpha():
res += s[self.i]
elif s[self.i] == '[':
#递归调用
res += self.decodeString(s) * num
num = 0
elif s[self.i] == ']':
return res
return res
``````

1人点赞

• 1
• 评论
• 收藏
• 共同学习，写下你的评论

0/150