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]
2、解题思路
-
使用栈处理嵌套结构:栈可以帮助我们处理嵌套的编码字符串,每次遇到
]时,处理最近的一个[之间的字符串。 -
遍历字符串:逐个字符处理字符串,分为以下几种情况:
-
数字:读取完整的数字(可能有多位),并将其压入栈。
-
字母或
[:直接压入栈。 -
]:开始处理,从栈中弹出字符直到遇到[,然后弹出数字,将字符串重复数字指定的次数后重新压入栈。
-
-
辅助方法:
-
getDigits:读取完整的数字字符串。 -
getString:将字符串列表拼接成一个字符串。
-
class Solution {
int ptr;
public String decodeString(String s) {
LinkedList<String> stk = new LinkedList<>();
ptr = 0;
while (ptr<s.length()){
char cur = s.charAt(ptr);
if (Character.isDigit(cur)){//如果是数字,需要对数字进行处理,因为如果是12,读取的是1,但是咱们需要的是12
//处理数字,使数字完整
String digits = getDigits(s);
stk.addLast(digits);
}else if (Character.isLetter(cur) || cur == '['){
//处理普通字符和‘【’,压入栈
stk.addLast(String.valueOf(s.charAt(ptr++)));//将字符转为字符串,压入栈
}else {
//遇见‘】’,处理想匹配的‘【’之间的字符,需要根据前面的数值对字符进行重复
++ptr;
//使用另一个list,将字符串进行组合
LinkedList<String> sub = new LinkedList<>();
while (!"[".equals(stk.peekLast())){
sub.addLast(stk.removeLast());
}
//因为栈的特点,导致组合字符串和原本的字符串相比是倒序的
//需要进行字符串反转
Collections.reverse(sub);
//左括号出栈
stk.removeLast();
//此时栈顶为当前的sub,对应的字符串应该出现的次数
int repTime = Integer.parseInt(stk.removeLast());
StringBuffer t = new StringBuffer();
String o = getString(sub);
//构造字符串
while (repTime-- > 0){
t.append(o);
}
//构造好的字符串入栈
stk.addLast(t.toString());
}
}
return getString(stk);
}
public String getDigits(String s) {
StringBuffer ret = new StringBuffer();
while (Character.isDigit(s.charAt(ptr))){
ret.append(s.charAt(ptr++));
}
return ret.toString();
}
public String getString(LinkedList<String> v) {
StringBuffer ret = new StringBuffer();
for (String s : v) {
ret.append(s);
}
return ret.toString();
}
}
467

被折叠的 条评论
为什么被折叠?



