刷
July-17-2019
一开始用Stack做的,来回倒腾:
不是右括号进栈
右括号的话就开始POP找左括号,找到就有了需要重复的String,然后看重复几次,重复完了司塞回去继续。
有很多edge case忽略了,比如digit大于10;经常要reverse之类的
class Solution {
public String decodeString(String s) {
ArrayDeque<Character> stack = new ArrayDeque<>();
int i = 0;
StringBuilder res = new StringBuilder();
while (i < s.length()) {
char c = s.charAt(i);
if (c != ']') {
stack.push(c);
} else {
StringBuilder tempSb = new StringBuilder();
char tempC = stack.pop();
while (tempC != '[') {
tempSb.append(tempC);
tempC = stack.pop();
}
int repeatCount = getRepeatCount(stack);
String tempStr = tempSb.toString();
for (int j = 1; j < repeatCount; j ++) {
tempSb.append(tempStr);
}
tempStr = tempSb.reverse().toString();
for (int j = 0; j < tempStr.length(); j ++) {
stack.push(tempStr.charAt(j));
}
}
i ++;
}
while (!stack.isEmpty()) {
res.append(stack.pop());
}
return res.reverse().toString();
}
private int getRepeatCount(ArrayDeque<Character> stack) {
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty() && Character.isDigit(stack.peek())) {
sb.append(stack.pop());
}
return Integer.valueOf(sb.reverse().toString());
}
}
看以前自己写的答案,可以不用STACK直接干,或者说用RECURSION来替代Stack。
找到左括号之后一直往右找到和它同级的右括号。
3[abc4[de]]来说:
DECODE(3[abc4[de]]) = > DECODE(3[DECODE(abc4[de])])
找到第一层3[abc4[de]]把里面的abc4[de]直接传入下层decode()做recursion call,回来再乘以重复的次数。
其实abc = 1[a]1[b]1[c],相当于1不用算了
class Solution {
public String decodeString(String s) {
StringBuilder res = new StringBuilder();
int i = 0;
while (i < s.length()) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
// get repeat times
int repeatCount = c - '0';
i ++;
while (Character.isDigit(s.charAt(i))) {
repeatCount = repeatCount * 10 + s.charAt(i ++) - '0';
}
// remember start position of string taht goes to next level recursion call
int startIndex = ++i;
// find end position of string that goes to next level recursion call
// based on open parenthesis
int openParentheses = 1;
while (openParentheses != 0) {
char tempChar = s.charAt(i);
if (tempChar == '[') {
openParentheses ++;
} else if (tempChar == ']') {
openParentheses --;
}
i ++;
}
i --;
// goes to next call and report X times
String innerStr = decodeString(s.substring(startIndex, i));
for (int j = 0; j < repeatCount; j ++) {
res.append(innerStr);
}
i ++;
} else {
res.append(c);
i ++;
}
}
return res.toString();
}
}
三刷
12-Jan-2017
可以确定思路是DFS+Stack。
可以纯用STACK手动操作,也可以通过dfs的memory stack来记录 which is much easier..
对于一个String:
232[ vSDFSADS ]
只要确定前面的数字 232,和跟随他的大括号的范围就行了。
当然大括号里面可能嵌套别的 数字[fsdf] 这样的组合,所以关键是定位跟随大括号的位置。
也很简单,左边括号数量 = 右边括号数的时候,就是该进入next depth的范围。
Time: 指数级别的? 范围定位在最后的话,搜索过去就算遍历过一次这个pattern了。。但是这个pattern还要进入下一层。。
Space: memory stack..depends on how deep our search goes
public class Solution {
public String decodeString(String s) {
if (s.length() <= 1) return s;
int i = 0;
StringBuilder res = new StringBuilder();
while (i < s.length()) {
char c = s.charAt(i);
// find a digit, meaning we're gonna go deeper
if (Character.isDigit(c)) {
// get digit
int num = 0;
while (i < s.length() && Character.isDigit(c)) {
num = num * 10 + c - '0';
c = s.charAt(++i);
}
// search for index of the pattern which goes to next depth
int start = ++i;
int leftNum = 1;
while (i < s.length()) {
if (s.charAt(i) == '[') {
leftNum ++;
} else if (s.charAt(i) == ']') {
if (--leftNum == 0) {
break;
}
}
i++;
}
// s.substring(start, i) goes to next level
String tempStr = decodeString(s.substring(start, i));
// repeat num times
while (num > 0) {
res.append(tempStr);
num --;
}
i ++;
} else if (Character.isAlphabetic(c)) {
// we ain't do shit if it's simply a letter.. and not in []
res.append(c);
i ++;
}
}
return res.toString();
}
}