- 2.14
- 如果 第一个stack 选为 pop push,需要在最后结果返回时反转。所以推荐使用 addLast 和 removeLast
- 判断数字和单词的 API 为 Character 的
- 第四次做知道大体的思路了
class Solution {
int cur=0;
Deque<String> stack = new LinkedList<>();
public String decodeString(String s) {
while(cur!=s.length()){
char ch = s.charAt(cur);
if(Character.isDigit(ch)){
String digits = getDigits(s);
stack.push(digits);
}else if(Character.isLetter(ch)||ch=='['){
stack.push(String.valueOf(s.charAt(cur++)));
}else{
cur++;
LinkedList<String> list = new LinkedList<>();
while(!"[".equals(stack.peek())){
list.addLast(stack.pop());
}
Collections.reverse(list);
stack.pop();
StringBuffer sb = new StringBuffer();
int times = Integer.valueOf(stack.pop());
String string = getString(list);
while(times-- >0){
sb.append(string);
}
stack.push(sb.toString());
}
}
StringBuffer sb = new StringBuffer();
while(!stack.isEmpty()){
sb.append(stack.pollLast());
}
return sb.toString();
}
public String getDigits(String s){
StringBuffer sb = new StringBuffer();
while(Character.isDigit(s.charAt(cur))){
sb.append(s.charAt(cur++));
}
return sb.toString();
}
public String getString(Deque<String> stack){
StringBuffer sb = new StringBuffer();
for(String s:stack){
sb.append(s);
}
return sb.toString();
}
}class Solution {
public String decodeString(String s) {
int cur=0;
Deque<Character> stack = new LinkedList<>();
while(cur!=s.length()){
char ch = s.charAt(cur);
if(ch.isDigit()){
String digits = getDigits(ch);
stack.push(digits.toCharArray());
}else if(ch.isLetter()||ch=='['){
stack.push(ch);
}else{
stack.pop();
LinkedList<Character> list = new LinkedList<>();
while(stack.peek()!='['){
list.addLast(stack.pop());
}
Collections.reverse(list);
StringBuffer sb = new StringBuffer();
int o = Integer.valueOf(stack.pop());
String l = getString(stack.pop());
while(o--){
sb.append(l);
}
}
return stack.toString();
}
}
}
- 2.1
- 判断是否是数字或者字母是 Character 内的方法,取数字用 Integer 的方法
- 用 tempStack 暂存 string 字符,并记得返回去
- getDigit 内指针会移动
- getString for 取出栈中的 string
“用一个栈从左到右扫描:数字入栈、字母和 [ 入栈;遇到 ] 时弹出到最近的 [,得到子串,再取出前面的重复次数,重复拼接后入栈。最后把栈中所有片段拼起来就是答案。时间空间都是 O(n)。”
-
11.18
- 上面说的没错
- Character有判断数字和字母的api
- 判断是数字,用自创函数取出完整数字放入总resStack
- 如果是字母或左括号,string化后放入总resStack
- 最后如果是右括号,匹配完成
- 弹出到左括号到新LinkedList,反转后,在弹出数字
- LinkedList里用自创函数得到完整String,然后数字×Stirng存入resStack
- 自创函数处理resStack
-
11.21
- 取数字时,传进去的是整个字符(ptr是全局变量)
- 取字母时,就地addlast(valueOf)
- 需要一个getString的方法来处理栈中零散的String
!"[".equals(stk.peekLast())这里是String的比较所以是双引号
class Solution {
int ptr;
public String decodeString(String s) {
Deque<String> stk = new LinkedList<>();
ptr = 0;
//1.注意ptr拼写
while(ptr<s.length()){
char ch = s.charAt(ptr);
//2.Character.isDigir()的API
if(Character.isDigit(ch)){
//3.getDigits:取出完整的数字而不是单个数字
String digits = getDigits(s);
stk.addLast(digits);
//4.Character.isLetter()API
}else if(Character.isLetter(ch)||ch=='['){
//5.String.valueOf()API
stk.addLast(String.valueOf(s.charAt(ptr++)));
}else{//匹配到了]?
//6.ptr只是一个全局游标指针,告诉前面已经处理了
ptr++;
LinkedList<String> sub = new LinkedList<>();
while(!"[".equals(stk.peekLast())){
sub.addLast(stk.removeLast());
}
Collections.reverse(sub);
stk.removeLast();
//7.转换为Int的Integer.parseInt()API
int repTime = Integer.parseInt(stk.removeLast());
StringBuffer sb = new StringBuffer();
String o = getString(sub);
while(repTime-- >0){
sb.append(o);
}
stk.addLast(sb.toString());
}
}
return getString(stk);
}
public String getDigits(String s){
StringBuffer sb = new StringBuffer();
while(Character.isDigit(s.charAt(ptr))){
sb.append(s.charAt(ptr++));
}
return sb.toString();
}
public String getString(Deque<String> stk){
StringBuffer sb = new StringBuffer();
for(String s:stk){
sb.append(s);
}
return sb.toString();
}
}
用到的 Java API 清单
字符/字符串处理 • s.charAt(ptr):读取当前位置字符 • s.length():边界判断 • Character.isDigit(ch):判断是否数字 • Character.isLetter(ch):判断是否字母 • String.valueOf(ch):把 char 转为 String • (推荐)StringBuilder / (你代码里)StringBuffer:高效拼接字符串 • append(…)、toString()
1. 从左到右扫描字符串,用一个栈暂存“数字 / 左括号 / 普通字母 / 已展开片段”。
2. 遇到:
• 数字:把连续的数字读完(可能多位),入栈。
• 字母或**[**:直接入栈。
• ]:开始出栈还原最近一段:
• 弹出直到遇到"["的所有字符串,拼成一个子串 o(注意顺序)。
• 弹出左括号 "["。
• 再弹出其前面的重复次数 repTime。
• 构造 repTime 次 o 的重复,压回栈。
3. 扫描结束后,把栈里剩余内容按顺序拼接就是结果。
关键点 • 多位数:12[a] 必须一次性读成 “12”;不能只取当前字符。 • 顺序:从栈里往外弹出的子串是逆序的,记得反转或用 addFirst 还原。 • 指针移动:读到 ] 时需要 ptr++ 跳过它,继续往右走。 • 时间复杂度:O(n);空间复杂度:O(n)(栈存中间结果)。
Deque