1. LeetCode 232.用栈实现队列
题目链接:https://leetcode.cn/problems/implement-queue-using-stacks/description/
文章链接:https://programmercarl.com/0232.%E7%94%A8%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
视频链接:https://www.bilibili.com/video/BV1nY4y1w7VC
思路:
使用两个栈,一个输入栈,一个输出栈。
关于队列和栈的函数总结:
1.队列:
添加元素:
offer():将元素加入队列的尾部
获取元素:
poll():返回队列的队头元素,并删除该元素。
peek():返回队列队头元素,并不删除该元素。
2.栈:
添加元素:
push():将元素加入栈的栈顶
获取元素:
pop():返回栈的栈顶元素,并删除该元素。
peek():返回栈的栈顶元素,并不删除该元素。
解法:
class MyQueue {
Stack<Integer> inStack;//输入栈
Stack<Integer> outStack;//输出栈
public MyQueue() {
inStack = new Stack<>();
outStack = new Stack<>();
}
public void push(int x) {
inStack.push(x);
}
public int pop() {
move();
return outStack.pop();
}
public void move(){
if(!outStack.isEmpty()) return;
else{
while(!inStack.isEmpty()){
outStack.push(inStack.pop());
}
return;
}
}
public int peek() {
move();
return outStack.peek();
}
public boolean empty() {
return inStack.isEmpty()&&outStack.isEmpty();
}
}
/**
* 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();
*/
2.LeetCode 225. 用队列实现栈
题目链接:https://leetcode.cn/problems/implement-stack-using-queues/description/、
文章链接:https://www.programmercarl.com/0225.%E7%94%A8%E9%98%9F%E5%88%97%E5%AE%9E%E7%8E%B0%E6%A0%88.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
视频链接:https://www.bilibili.com/video/BV1Fd4y1K7sm
思路:
可以使用两个队列或者一个队列实现栈。
两个队列实现时,其中一个队列只负责存储数据,另外一个队列负责保证内部数据顺序和栈相同。
一个队列实现时,每次栈要移除一个元素,都是将队列中除了最后一个元素外的所有元素,都移动到队列的结尾,使得队列的头元素是未移动之前的最后一个元素。
// //使用两个队列
// class MyStack {
// Queue<Integer> queue1;//内部元素顺序与栈一致
// Queue<Integer> queue2;//临时存放元素
// public MyStack() {
// queue1=new ArrayDeque();
// queue2=new ArrayDeque();
// }
// public void push(int x) {
// queue2.offer(x);
// while(!queue1.isEmpty()){
// queue2.offer(queue1.poll());
// }
// Queue temp=queue2;
// queue2=queue1;
// queue1=temp;
// }
// public int pop() {
// return queue1.poll();
// }
// public int top() {
// return queue1.peek();
// }
// public boolean empty() {
// return queue1.isEmpty();
// }
// }
//使用一个队列
class MyStack {
Queue<Integer> queue;
public MyStack() {
queue=new ArrayDeque();
}
public void push(int x) {
queue.offer(x);
}
public int pop() {
position();
return queue.poll();
}
public int top() {
position();
int res=queue.poll();
queue.offer(res);
return res;
}
public boolean empty() {
return queue.isEmpty();
}
public void position(){
int len=queue.size();
len--;
while(len>0){
queue.offer(queue.poll());
len--;
}
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
3.LeetCode 20. 有效的括号
题目链接:https://leetcode.cn/problems/valid-parentheses/description/
文章链接:https://www.programmercarl.com/0020.%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
视频链接:https://www.bilibili.com/video/BV1AF411w78g
思路:
有三种不匹配的情况:
1.第一种情况,字符串里左方向的括号多余了 ,所以不匹配。
2.第二种情况,括号没有多余,但是 括号的类型没有匹配上。
3.第三种情况,字符串里右方向的括号多余了,所以不匹配。
分析:
遍历字符串,碰到左括号就将对应的右括号加入栈中;碰到右括号时,检查该右括号与栈顶括号是否一致,一致则代表一个左括号匹配成功,将其出栈;否则匹配失败。
第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false (左括号多了)
第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false
第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false (右括号多了)
当字符串遍历完之后,栈是空的,就说明全都匹配了。
注意:栈中只存放右括号。
解法:
class Solution {
public boolean isValid(String s) {
Deque<Character> deque=new ArrayDeque<>();
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='('){
deque.push(')');
}else if(s.charAt(i)=='{'){
deque.push('}');
}else if(s.charAt(i)=='['){
deque.push(']');
}else if(deque.isEmpty()||deque.peek()!=s.charAt(i)){//空了代表右括号多了或者类型不匹配
return false;
}else{//类型匹配
deque.pop();
}
}
return deque.isEmpty();//未空则代表左括号多了
}
}
4.LeetCode 1047. 删除字符串中的所有相邻
题目链接:https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/description/
文章链接:https://www.programmercarl.com/1047.%E5%88%A0%E9%99%A4%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E6%89%80%E6%9C%89%E7%9B%B8%E9%82%BB%E9%87%8D%E5%A4%8D%E9%A1%B9.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
视频链接:https://www.bilibili.com/video/BV12a411P7mw
思路:
使用栈存放遍历过的元素:
当遍历当前的这个元素的时候,检查是否与栈顶元素相同,若不相同,则加入栈中;若相同,则pop()出栈顶元素,做消除操作。
从栈中弹出剩余元素,因为从栈里弹出的元素是倒序的,所以再对字符串进行反转一下,就得到了最终的结果。
解法:
class Solution {
public String removeDuplicates(String s) {
Deque<Character> deque=new ArrayDeque<>();
for(int i=0;i<s.length();i++){
char ch=s.charAt(i);
if(deque.isEmpty()||deque.peek()!=ch){// 当前字符与栈顶字符不相同
deque.push(ch);
}else{
deque.pop();
}
}
String str = "";
//剩余的元素即为不重复的元素
while (!deque.isEmpty()) {
str = deque.pop() + str;
}
return str;
}
}