一. 有效的括号
题目链接:力扣
思路:无非三种情况:
1. 左侧括号多,右侧少
2. 左右侧一样多,该字符串属于有小括号字符串
3. 右侧括号多,左侧少
那么说白了就是要比较左右括号的数量,谁多,谁少,还是相等。
代码:
class Solution {
public boolean isValid(String s) {
Deque<Character> deque = new LinkedList<>();
char ch;
for (int i = 0; i<s.length(); i++) {
//将字符串中的字符一个一个取出
ch = s.charAt(i);
//碰到左括号就将右括号入栈
if(ch=='(') {
deque.push(')');
} else if(ch=='{') {
deque.push('}');
} else if(ch=='[') {
deque.push(']');
//若栈为空,证明一个入栈的括号都没有,该字符串根本没有括号
//如何判断结束?这里使用了短路或
//因此首先栈为空,而且栈顶元素不为当前的元素 证明遍历结束了
} else if(deque.isEmpty() || deque.peek() != ch){
return false;
} else {
//若是右括号,检查是否和栈顶元素匹配
deque.pop();
}
}
//判断栈中元素是否匹配
return deque.isEmpty();
}
}
二. 删除字符串中的所有相邻重复项
题目链接:力扣
思路:还是扫描,跟上一道题中扫描括号的方法类似,只是从扫描括号变成了扫描单个字符。
扫到第一个就加进去,再扫到就删除,然后将元素逆序输出即可。
这里录哥的gif非常好懂,几乎是看一眼就明白了,推荐!
动态图网址:代码随想录
代码:
class Solution {
public String removeDuplicates(String s) {
ArrayDeque<Character> que = new ArrayDeque<>();
char c;
for(int i=0; i<s.length(); i++) {
c = s.charAt(i);
//若栈为空,且栈顶和当前元素不相等,证明没有相邻
if(que.isEmpty() || que.peek() != c) {
//将其压入栈内
que.push(c);
} else { //若上述条件通过,证明栈顶和当前元素相等,即 相邻,将该元素弹出栈
que.pop();
}
}
//经过上述操作,剩余元素便为不重复元素,将其转换为字符串返回
String str = "";
while(!que.isEmpty()) {
//通过push入栈,再通过pop出栈,实现逆序
str = que.pop() + str;
}
//将字符串返回
return str;
}
}
三. 逆波兰式求值
题目链接:力扣
思路:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中。
代码:
class Solution {
public int evalRPN(String[] tokens) {
Deque<Integer> que = new LinkedList<>();
for(String s : tokens) {
if("+".equals(s)) {
//将刚入栈的俩元素弹出来,进行“+”运算,运算结束后再push压进栈
que.push(que.pop() + que.pop());
} else if("-".equals(s)) {
que.push(-que.pop() + que.pop());
} else if("*".equals(s)) {
que.push(que.pop() * que.pop());
} else if("/".equals(s)) {
//因为除法是前面的除以后面的,所以需要交换顺序
int temp1 = que.pop();
int temp2 = que.pop();
que.push(temp2 / temp1);
} else {
//若是数字,直接将字符串转换为int,进栈
que.push(Integer.valueOf(s));
}
}
//将计算完毕的数返回
return que.pop();
}
}