复习一下栈和队列的基础知识,刷几道题上上手。
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();
}
}