代码随想录算法训练营day11 | 20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值
20. 有效的括号
教程视频:
字符串无效有三种情况:
1、左括号多;
2、左右括号数量一样但类型不匹配;
3、右括号多;
这三种情况对应三种栈情况:
1、遍历完字符串,栈不为空;
2、没遍历完字符串,栈顶元素和所需元素不匹配;
3、没遍历完字符串,栈已经空了。
解法一:Stack实现
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for(int i=0; i<s.length(); i++){
if(s.charAt(i)=='('){
stack.push(')');
}else if(s.charAt(i)=='['){
stack.push(']');
}else if(s.charAt(i)=='{'){
stack.push('}');
//无效情况2、3
}else if(stack.empty() || s.charAt(i)!=stack.peek()){
return false;
}else{
stack.pop();
}
}
//无效情况1
return stack.empty();
}
解法二:Deque
public boolean isValid(String s) {
Deque<Character> que = new LinkedList<>();
int i =0;
while(i<s.length()){
if(s.charAt(i)=='('){
que.offerFirst(')');
}else if(s.charAt(i)=='{'){
que.offerFirst('}');
}else if(s.charAt(i)=='['){
que.offerFirst(']');
}else if(que.isEmpty() || s.charAt(i)!=que.peekFirst()){
return false;
}else{
que.pollFirst();
}
i++;
}
return que.isEmpty();
}
1047. 删除字符串中的所有相邻重复项
教程视频:
解法一:Deque
public String removeDuplicates(String s) {
Deque<Character> deque = new LinkedList();
Character ch;
for(int i=0; i<s.length(); i++){
ch = s.charAt(i);
if(deque.isEmpty() || deque.peekFirst()!=ch){
deque.offerFirst(ch);
}else{
deque.pollFirst();
}
}
String result = new String();
while(!deque.isEmpty()){
result = deque.pollFirst()+result;
}
return result;
}
解法二:拿字符串直接作为栈
public String removeDuplicates(String s) {
// StringBuilder res = new StringBuilder();
StringBuffer res = new StringBuffer();
// top为 res 的指针
int top = -1;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// 当 top > 0,即栈中有字符时,当前字符如果和栈中字符相等,弹出栈顶字符,同时 top--
if (top >= 0 && res.charAt(top) == c) {
res.deleteCharAt(top);
top--;
// 否则,将该字符 入栈,同时top++
} else {
res.append(c);
top++;
}
}
return res.toString();
}
150. 逆波兰表达式求值
教程视频:
解法
这里注意不要用StringBuffer当栈,因为有的数字不止一个字符,会出错。
public int evalRPN(String[] tokens) {
Deque<Integer> que = new LinkedList<>();
for(int i=0; i<tokens.length; i++){
if("+".equals(tokens[i])){
que.push(que.pop()+que.pop());
}else if("-".equals(tokens[i])){
que.push(-que.pop()+que.pop());
}else if("*".equals(tokens[i])){
que.push(que.pop()*que.pop());
}else if("/".equals(tokens[i])){
//注意这里先弹出的是除数
int temp1 = que.pop();
int temp2 = que.pop();
que.push(temp2/temp1);
}else {
que.push(Integer.parseInt(tokens[i]));
}
}
return que.pop();
}
总结
1、遇到折叠相关问题考虑使用栈结构。