题目描述
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: 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”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/decode-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
栈
class Solution {
private static int point;
public static String decodeString(String s) {
LinkedList<String> results = new LinkedList<String>();
point = 0;
// 从零开始 循环字符串里的字符
while(s.length() > point){
char curr = s.charAt(point);
if(Character.isDigit(curr)){
// 如果是该字符是数字就一直找到所有数字 并且放进栈
results.add(getDigits(s));
}else if(Character.isLetter(curr) || curr == '['){
// 如果该字符是字母或“[”就下一个字符放进栈
results.add(String.valueOf(curr));
point++;
}else{
// 既不是数字也不是字母不是“[" 说明就是“]”
// 新增临时字符串 链表
LinkedList<String> tempList = new LinkedList<String>();
// 把“["到现在位置的“]” 中间的东西拿出来 放在临时字符串里
while(!results.peekLast().equals("[")){
tempList.add(results.removeLast());
}
// 左括号“["出栈 在这里 一个小问题就解决完毕了
results.pollLast();
// 把临时字符串的顺序颠倒 获得字符串形式的中间内容
Collections.reverse(tempList);
String tempStr = getString(tempList);
// 此时栈顶为当前 sub 对应的字符串应该出现的次数
int repeat = Integer.parseInt(results.removeLast());
StringBuffer newStr = new StringBuffer();
// 按照倍数重复临时字符串
while(repeat --> 0){
newStr.append(tempStr);
}
//把处理好的字符串继续加入链表 继续后面的循环
results.addLast(newStr.toString());
//读下一个字符
point++;
}
}
return getString(results);
}
public static String getDigits(String s) {
StringBuffer stringBuffer = new StringBuffer();
while(Character.isDigit(s.charAt(point))){
stringBuffer.append(s.charAt(point++));
}
return stringBuffer.toString();
}
public static String getString(LinkedList<String> ns) {
StringBuffer stringBuffer = new StringBuffer();
for(String n: ns){
stringBuffer.append(n);
}
return stringBuffer.toString();
}
}
递归
把问题分解成 数字[]
class Solution {
String src;
int ptr;
public String decodeString(String s) {
src = s;
ptr = 0;
return getString();
}
public String getString() {
if (ptr == src.length() || src.charAt(ptr) == ']') {
// String -> EPS
return "";
}
char cur = src.charAt(ptr);
int repTime = 1;
String ret = "";
if (Character.isDigit(cur)) {
// String -> Digits [ String ] String
// 解析 Digits
repTime = getDigits();
// 过滤左括号
++ptr;
// 解析 String
String str = getString();
// 过滤右括号
++ptr;
// 构造字符串
while (repTime-- > 0) {
ret += str;
}
}
else if (Character.isLetter(cur)) {
// String -> Char String
// 解析 Char
ret = String.valueOf(src.charAt(ptr++));
}
return ret + getString();
}
public int getDigits() {
int ret = 0;
while (ptr < src.length() && Character.isDigit(src.charAt(ptr))) {
ret = ret * 10 + src.charAt(ptr++) - '0';
}
return ret;
}
}