Leetcode 20.有效的括号
栈的经典应用
熟悉java中队列和栈使用的语法
文章讲的很好,先看文章。
思路: 先分清三种情况;
思路动图:
自己写的代码:
// push(x) -- 将一个元素放入队列的尾部。
// pop() -- 从队列首部移除元素。
// peek() -- 返回队列首部的元素。
// empty() -- 返回队列是否为空。
// pop和peek功能相似,可封装一个方法,让他们两一起调用
class Solution {
public boolean isValid(String s) {
// deque即双端队列,是一种具有队列和栈的性质的数据结构,所以使用deque好一点
Deque<Character> deque = new LinkedList<>();
// 定义一个字符型变量
char ch;
// 可以直接用for循环和charAt(i)对字符串进行遍历
for(int i =0; i<s.length(); i++){
// 遍历字符数组,charAt(i)是查询i索引下的字符
ch = s.charAt(i);
// 遍历左括号,将对应的有括号值push入栈
if(ch == '('){
deque.push(')');
}else if(ch == '['){
deque.push(']');
}else if(ch == '{'){
deque.push('}');
// 第三种情况:判断是否为空deque.isEmpty()遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
// 第二种情况:遍历字符串匹配的过程中,deque.peek() != ch判断栈顶元素是否等于右括号,发现栈里没有我们要匹配的字符。所以return false
}else if(deque.isEmpty() || deque.peek() != ch){
return false;
// 否则栈顶元素等于ch,则用pop()弹出栈顶元素
}else{
deque.pop();
}
}
// 第一种情况:此时我们已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return true
return deque.isEmpty();
}
}
Leetcode 1047. 删除字符串中的所有相邻重复项
栈的经典应用。
要知道栈为什么适合做这种类似于爱消除的操作,因为栈帮助我们记录了 遍历数组当前元素时候,前一个元素是什么。
题目链接/文章讲解/视频讲解:
思路简图:
自己写的代码:
// push(x) -- 将一个元素放入队列的尾部。
// pop() -- 从队列首部移除元素。
// peek() -- 返回队列首部的元素。
// empty() -- 返回队列是否为空。
// pop和peek功能相似,可封装一个方法,让他们两一起调用
class Solution {
public String removeDuplicates(String s) {
//ArrayDeque会比LinkedList在除了删除元素这一点外会快一点
ArrayDeque<Character> deque = new ArrayDeque<>();
char ch;
for(int i = 0; i < s.length(); i++){
ch = s.charAt(i);
// 因为要删除的是相邻且相等的项,所以相同的项一定会在栈顶,所以可以用peek()
if(deque.isEmpty() || deque.peek() != ch){
deque.push(ch);
}else{
deque.pop();
}
}
// 将栈内剩余元素导出为字符串,栈转为字符串
String str = "";
//剩余的元素即为不重复的元素,deque里的值要用pop一个一个给,所以需要循环来做
while(!deque.isEmpty()){
str = deque.pop() + str;
}
return str;
}
}
Leetcode 150. 逆波兰表达式求值
本题不难,但第一次做的话,会很难想到,所以先看视频,了解思路再去做题
题目链接/文章讲解/视频讲解:
逆波兰表达式:是一种后缀表达式,所谓后缀就是指运算符写在后面。
平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
逆波兰表达式主要有以下两个优点:
-
去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
-
适合用栈操作运算:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中。
思路简图:
自己写的代码:
class Solution {
public int evalRPN(String[] tokens) {
ArrayDeque<Integer> stack = new ArrayDeque<>();
for (String s : tokens) {
if ("+".equals(s)) { // leetcode 内置jdk的问题,不能使用==判断字符串是否相等
stack.push(stack.pop() + stack.pop()); // 注意 - 和/ 需要特殊处理
} else if ("-".equals(s)) {
stack.push(-stack.pop() + stack.pop());
} else if ("*".equals(s)) {
stack.push(stack.pop() * stack.pop());
} else if ("/".equals(s)) {
int temp1 = stack.pop();
int temp2 = stack.pop();
stack.push(temp2 / temp1);
} else {
stack.push(Integer.valueOf(s));
}
}
return stack.pop();
}
}