字符串解码——LeetCode394题详解
一、题目描述
给定特点编码格式的字符串,要求解码。编码的字符串中数字代表一对[]里面字符串的数字。
例如: 原编码字符串:3[a2[c]] 解码后字符串:accaccacc
二、算法思想
1、借助栈的思想
算法:
对于这里的字符串的解码,最特殊的就是内嵌的形式,所以要从里往外解码。这就自然而然想到栈“先进后出”的特点。
设置变量:ans,mulit,遍历字符串
- 如果当前字符为数字字符,将mulit累加当前值;
- 如果当前字符是'[',将mulit入栈,ans入栈,然后将mulit,ans重置;
- 如果当前字符是']',将栈里面最后一个mulit出栈,然后将当前ans叠加mulit遍,然后栈里面最后一个ans出栈,加上当前ans;
- 如果当前字符时字母型,直接入栈。
代码实现:
public static String decodeString(String s) { StringBuilder res=new StringBuilder(); LinkedList<Integer> mul_List=new LinkedList<>(); LinkedList<String> res_List=new LinkedList<>(); int multi=0; for (Character c:s.toCharArray()) { if(c=='['){ mul_List.addLast(multi); res_List.addLast(res.toString()); // 置空 multi=0; res=new StringBuilder(); } else if(c==']'){ StringBuilder tmp=new StringBuilder(); int curmulti=mul_List.removeLast(); for (int j = 0; j < curmulti; j++) { tmp.append(res); } res=new StringBuilder(res_List.removeLast()+tmp); } else if(c>='0'&&c<='9'){ multi = multi * 10 + Integer.parseInt(c + "");; } else { res.append(c); } } return res.toString(); }
2、递归
算法:
对于每个[]里面的操纵都是一样的,这就自然想到使用递归,但这里有内嵌的情况,所以处理起来比较特殊。
首先我们定义递归函数dfs(String s, int i),将原字符串和当前'['字符出现的位置传进去。
同样设置变量:ans,mulit,从i开始遍历字符串
- 如果当前字符为数字字符,将mulit累加当前值;
- 如果当前字符是'[',开始下一轮递归,并且将结果保存到当前;
- 如果当前字符是']',返回当前ans,和']'的位置i;
- 如果当前字符时字母型,直接入栈。
代码实现:
public static String decodeString(String s){ return dfs(s,0)[0]; } private static String[] dfs(String s,int i) { StringBuilder ans=new StringBuilder(); int multi=0; while (i<s.length()){ char c=s.charAt(i); if(c>='0'&&c<='9'){ multi = multi * 10 + Integer.parseInt(String.valueOf(c)); } else if(c=='['){ String[] tmp=dfs(s,i+1); i=Integer.parseInt(tmp[0]); while (multi>0){ ans.append(tmp[1]); multi--; } } else if(c==']'){ return new String[] {String.valueOf(i),ans.toString()}; } else { ans.append(c); } i++; } return new String[] {ans.toString()}; }