232.用栈实现队列
题目链接 | 文档讲解 |视频讲解 : 链接
1.思路:
-
使用2个栈去实现队列
-
先将元素放入栈1中,然后在将栈1中的元素出栈到栈2中,栈2的元素出栈顺序就和队列的出队一样
2.代码:
class MyQueue {Stack<Integer> stackIn;Stack<Integer> stackOut;public MyQueue() {//负责入队stackIn=new Stack<>();//负责出队stackOut=new Stack<>();}public void push(int x) {stackIn.push(x); }public int pop() {judge();return stackOut.pop(); }public int peek() {judge();return stackOut.peek();}public boolean empty() {//输入和输出栈都为空,说明队列为空return stackIn.isEmpty() && stackOut.isEmpty();}public void judge(){if(!stackOut.isEmpty()){return;}while(!stackIn.isEmpty()){stackOut.push(stackIn.pop());}}
}/*** Your MyQueue object will be instantiated and called as such:* MyQueue obj = new MyQueue();* obj.push(x);* int param_2 = obj.pop();* int param_3 = obj.peek();* boolean param_4 = obj.empty();*/
225. 用队列实现栈
题目链接 | 文档讲解 |视频讲解:链接
1.思路:
-
使用2个队列实现,一个用于保持与栈的出入顺序一致 q1,另一个用于辅助q2
-
push():利用两个队列,完成元素的倒腾,使得新加入的元素称为栈顶
-
pop(): 由于push的时候已经与栈顺序元素一致,直接返回队首即可
-
top(): 同上
-
empty() :只需要判断q1
2.代码:
public class MyStack {//与栈的出入顺序保持一致Queue<Integer> q1 = new ArrayDeque<>();//辅助Queue<Integer> q2 = new ArrayDeque<>();public MyStack() {}public void push(int x) {//放入 [1,2]//1:q1[1] q2[]//2: q1[] q2[1] ------ q1[2,1] q2[]//将q1元素倒入q2while (q1.size()>0){q2.add(q1.poll());}//将元素放入q1中q1.add(x);//将q2元素倒回q1,把持栈顶在最前面while (q2.size()>0){q1.add(q2.poll());}}public int pop() {return q1.poll();}public int top() {return q1.peek();}public boolean empty() {return q1.isEmpty();}
}
1.思路:
使用一个双端队列实现栈
push使用 ArrayDeque 在队尾添加元素,
pop的时候,将ArrayDeque中的size-1的元素先pollFirst()出去,在添加到队尾
2.代码:
public class MyStack2 {//Deque 接口继承了 Queue 接口//所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirstDeque<Integer> deque;public MyStack2() {deque=new ArrayDeque<>();}public void push(int x) {// 1 2//往队尾加deque.addLast(x);}public int pop() {int size = deque.size();size--;while (size-- > 0) {deque.addLast(deque.pollFirst());}return deque.pollFirst();}public int top() {//栈顶元素return deque.peekLast();}public boolean empty() {return deque.isEmpty();}
}
操作 | MyStack (两个队列) | MyStack2 (一个 Deque) |
---|---|---|
数据结构 | 两个普通队列 | 一个双端队列 |
push 位置 | 插入 q1,然后倒腾 q2,使新元素在队首 | 插入队尾 |
push 时间 | O(n),需要两次倒腾 | O(1),直接插入 |
pop 位置 | 直接从 q1 队首弹出 | 把前 n-1 个元素重新放到队尾,最后弹出 |
pop 时间 | O(1) | O(n) |
peek 时间 | O(1) | O(1) |
优点 | pop 快,适合频繁出栈场景 | 结构简单,空间少 |
缺点 | 空间多,push 慢 | pop 慢,不适合频繁出栈 |
20. 有效的括号
题目链接 | 文档讲解 |视频讲解:链接
1.思路:
-
使用栈去解决
-
括号的类型有 (,{,[ 三种,如果当前遍历的元素时上述三种,则分别向栈中添加 ),},] ,如果当前遍历的元素不是上述三种情况,判断栈为空 || 栈顶元素与当前元素不相等,返回false
-
循环外,判断当前栈是否为空即可
2.代码:
public boolean isValid(String s) {Stack<Character> stack=new Stack<>();char [] arr=s.toCharArray();for(char c : arr){if(c == '('){stack.push(')');}else if(c =='{'){stack.push('}');}else if(c=='['){stack.push(']');} else if(stack.isEmpty() || c!= stack.pop()){return false;}}return stack.isEmpty();}
1047. 删除字符串中的所有相邻重复项
题目链接 | 文档讲解 |视频讲解:链接
1.思路:
-
使用栈去解决
-
当栈不为空且栈顶元素和当前遍历的元素一样,就将栈顶元素弹出去,其余情况就往栈中添加元素
-
栈中剩余的元素就是字符串中不重复的元素,但是与要求的元素的顺序是相反的,需要将顺序颠倒过来
2.代码:
public static String removeDuplicates(String str) {ArrayDeque<Character> queue = new ArrayDeque<>();for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);//当栈不为空且栈首元素和当前字符串所在元素一样,就弹出栈首if(!queue.isEmpty() && queue.peek()==c){queue.pop();}else{//往栈中添加元素queue.push(c);}}//剩余元素为不重复的元素String res="";while (!queue.isEmpty()){res=queue.pop()+res;}return res;}