复习一下栈和队列的基础知识,刷几道题上上手。
1、102. 二叉树的层序遍历
广度优先遍历嘛,每次拓展一个新结点,就把新结点加入队列,这样遍历完队列中的元素,顺序就是层序遍历。
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {LinkedBlockingQueue<TreeNode> q = new LinkedBlockingQueue<>();List<List<Integer>> list = new ArrayList<>();if(root == null) return list;q.offer(root);int cnt = 1;while(!q.isEmpty()){List<Integer> L = new ArrayList<>();int temp = 0;for(int i = 0; i < cnt; i++){TreeNode t = q.poll();L.add(t.val);if(t.left != null){q.offer(t.left);temp++;}if(t.right != null){q.offer(t.right);temp++;}}cnt = temp;list.add(L);}return list;}
}
2 、20. 有效的括号
有几种典型的适合用栈解决的问题,括号匹配就是。
class Solution {public boolean isValid(String s) {Stack<Character> stack = new Stack<>();for(int i = 0; i < s.length(); i++){char c = s.charAt(i);if(stack.isEmpty()){stack.push(c);continue;}if(stack.peek() == '(' && c == ')'){stack.pop();}else if(stack.peek() == '[' && c == ']'){stack.pop();}else if(stack.peek() == '{' && c == '}'){stack.pop();}else{stack.push(c);}}return stack.isEmpty();}
}
3、150. 逆波兰表达式求值
原来后缀表达式就叫逆波兰表达式啊,跟上个题也差不多,是数字就压栈,是操作符就取出来两个操作一下,然后把结果入栈,最后栈内肯定只有一个元素,这个元素就是答案。
学完了JVM之后,发现其实栈帧中的操作数栈就是使用的后缀表达式。
class Solution {public int evalRPN(String[] tokens) {Stack<Integer> s = new Stack<>();for(int i = 0; i < tokens.length; i++){if(tokens[i].equals("+")){int v1 = s.pop();int v2 = s.pop();s.push(v1 + v2);}else if(tokens[i].equals("-")){int v1 = s.pop();int v2 = s.pop();s.push(v2-v1);}else if(tokens[i].equals("*")){int v1 = s.pop();int v2 = s.pop();s.push(v1*v2);}else if(tokens[i].equals("/")){int v1 = s.pop();int v2 = s.pop();s.push(v2/v1);}else{s.push(Integer.valueOf(tokens[i]));}}return Integer.valueOf(s.pop());}
}
4、232. 用栈实现队列
队列是先进先出,栈是先进后出,那么来回倒腾这个栈就行了,画个图解释一下。
push操作都一样,pop的时候,把栈的元素移动到另一个栈内,这时候就是反转过的了,直接pop就行。
class MyQueue {Stack<Integer> s1 = null;Stack<Integer> s2 = null;public MyQueue() {s1 = new Stack<>();s2 = new Stack<>();}public void push(int x) {s2.push(x);}public int pop() {if(s1.isEmpty()){while(!s2.isEmpty()){s1.push(s2.pop());}}return s1.pop();}public int peek() {if(s1.isEmpty()){while(!s2.isEmpty()){s1.push(s2.pop());}}return s1.peek();}public boolean empty() {return s1.isEmpty()&&s2.isEmpty();}
}
5、225. 用队列实现栈
主要是push不同,每次push都把队列中的元素移动到另一个队列中,然后加入元素,然后再把另一个队列中的元素拿回来,这样这个队列就和栈一样了。
class MyStack {LinkedBlockingQueue<Integer> q1 = new LinkedBlockingQueue<>();LinkedBlockingQueue<Integer> q2 = new LinkedBlockingQueue<>();public MyStack() {}public void push(int x) {while(!q1.isEmpty()){q2.offer(q1.poll());}q1.offer(x);while(!q2.isEmpty()){q1.offer(q2.poll());}}public int pop() {return q1.poll();}public int top() {return q1.peek();}public boolean empty() {return q1.isEmpty();}
}