字符串解码
https://leetcode.cn/problems/decode-string/
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: 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”
解释:这道题中,字符串的数字表示括号内的字串出现几次。字串内又可以嵌套类似的形式。
在面试,这道题有两种解法,一种是递归,另一种非递归的方式则需要栈的思想。
public class Solution {
// 定义两个成员变量,表示原字符串和当前下标
String src;
int curIndex;
@Test
public void test() {
List<String> t = Arrays.asList("3(a2(bc))");
for (String s : t) {
System.out.println("递归:" + decodeString1(s));
System.out.println("非递归:" + decodeString2(s));
}
}
private String decodeString1(String str) {
if (str == null || str.length() == 0) {
return "";
}
src = str;
curIndex = 0;
return recursive();
}
private String recursive() {
if (curIndex == src.length() || src.charAt(curIndex) == ')') {
return "";
}
String ret = "";
int retTime = 0;
char cur = src.charAt(curIndex);
if (isLetter(cur)) {
ret = String.valueOf(cur);
++curIndex;
} else if (isDigit(cur)) {
retTime = getDigit();
curIndex++; // skip '('
String subStr = recursive();// notice
curIndex++; // skip ')'
StringBuffer buf = new StringBuffer();
while (retTime-- > 0) {
buf.append(subStr);
}
ret = buf.toString();
}
return ret + recursive();
}
private int getDigit() {
int ret = 0;
while (isDigit(src.charAt(curIndex))) {
ret = ret * 10 + (src.charAt(curIndex) - '0'); // notice
curIndex++;
}
return ret;
}
private boolean isDigit(char cur) {
if (cur >= '0' && cur <= '9') {
return true;
}
return false;
}
private boolean isLetter(char cur) {
if ((cur >= 'a' && cur <= 'z') || (cur >= 'A' && cur <= 'Z')) {
return true;
}
return false;
}
// 非递归形式
private String decodeString2(String str) {
if (str == null || str.length() == 0) {
return "";
}
src = str;
curIndex = 0;
// 定义一个栈,存放结果
LinkedList<String> stk = new LinkedList<String>();
while (curIndex < src.length()) {
char cur = src.charAt(curIndex);
if (isDigit(cur)) {
int retTime = getDigit();
stk.addLast(String.valueOf(retTime));
} else if (isLetter(cur) || cur == '[') {
stk.addLast(String.valueOf(cur));
curIndex++;
} else {
curIndex++; // skip ]
// 定义一个临时栈,生成子串
LinkedList<String> subStk = new LinkedList<String>();
while (!"[".equals(stk.peekLast())) {
subStk.addFirst(stk.removeLast());
}
String subStr = getStrFromStk(subStk);
stk.removeLast(); // pop '['
int retTime = Integer.valueOf(stk.removeLast());
StringBuffer buf = new StringBuffer();
while (retTime-- > 0) {
buf.append(subStr); // 按次数重复字串
}
stk.addLast(buf.toString());
}
}
return getStrFromStk(stk);
}
private String getStrFromStk(LinkedList<String> stk) {
StringBuffer buf = new StringBuffer();
for (String s : stk) {
buf.append(s);
}
return buf.toString();
}
}
递归结果
非递归结果