LeetCode_栈_困难_394.字符串解码
目录
- 1.题目
- 2.思路
- 3.代码实现(Java)
1.题目
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: 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”
提示:
1 <= s.length <= 30
s 由小写英文字母、数字和方括号 ‘[]’ 组成
s 保证是一个 有效 的输入。
s 中所有整数的取值范围为 [1, 300]
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/decode-string
2.思路
(1)栈
思路参考本题官方题解。
分析题目可知:经过编码的字符串可能会出现括号嵌套的情况,比如3[a2[c]],这种情况下可以先按照从内往外的顺序处理括号,即先将 3[a2[c]] 转化成 3[acc],然后再转化成 accaccacc。我们可以把字母、数字和括号看成是独立的 TOKEN,并用栈来维护这些 TOKEN。具体的做法是,遍历该字符串:
- 如果当前的字符为数,则解析出一个数字(或连续的多个数位)并将其进栈;
- 如果当前的字符为字母或者左括号,直接进栈;
- 如果当前的字符为右括号,则开始出栈,一直到左括号出栈,出栈序列反转后拼接成一个字符串,此时取出栈顶的数字(此时栈顶一定是数字),就是这个字符串应该出现的次数,我们根据这个次数和字符串构造出新的字符串并进栈。
重复上面的操作,最终将栈中的元素按照从栈底到栈顶的顺序拼接起来。
3.代码实现(Java)
//思路1————栈
class Solution {
int index;
public String decodeString(String s) {
//使用链表来模拟栈
LinkedList<String> stack = new LinkedList<>();
index = 0;
while (index < s.length()) {
char cur = s.charAt(index);
if (Character.isDigit(cur)) {
//获取一个数字 k 并进栈 (1 ≤ k ≤ 300)
String times = getDigits(s);
stack.push(times);
} else if (Character.isLetter(cur) || cur == '[') {
//获取一个字母并进栈
stack.push(String.valueOf(s.charAt(index++)));
} else {
//遇到 ']'
index++;
LinkedList<String> sub = new LinkedList<>();
while (!"[".equals(stack.peek())) {
sub.addFirst(stack.pop());
}
//左括号出栈
stack.pop();
//此时栈顶元素为当前 sub 对应的字符串应该出现的次数
int times = Integer.parseInt(stack.pop());
StringBuilder builder = new StringBuilder();
String str = getString(sub);
//构造字符串
while (times-- > 0) {
builder.append(str);
}
//将构造好的字符串加入到栈中
stack.push(builder.toString());
}
}
Collections.reverse(stack);
return getString(stack);
}
public String getDigits(String s) {
StringBuilder builder = new StringBuilder();
while (Character.isDigit(s.charAt(index))) {
builder.append(s.charAt(index++));
}
return builder.toString();
}
//拼接 stack 中的所有字符串并返回
public String getString(LinkedList<String> stack) {
StringBuilder builder = new StringBuilder();
for (String s : stack) {
builder.append(s);
}
return builder.toString();
}
}
还没有评论,来说两句吧...