目录
复习:
栈:后进先出
队列:先进先出
232.用栈实现队列
题目链接:https://leetcode.cn/problems/implement-queue-using-stacks/submissions/
思路:
利用栈要实现队列的“先进先出”,那需要设置两个“栈”,第一个栈用来加入内容(负责入栈),而第二个栈(负责出栈)一为空时,就要将第一个栈中的所有弹入第二个栈中。
class MyQueue {
Stack<Integer> stackIn;
Stack<Integer> stackOut;
public MyQueue() {
//设置两个栈
stackIn=new Stack<Integer>();//负责入栈
stackOut=new Stack<Integer>();//负责出栈
}
public void push(int x) {
stackIn.push(x);
}
public int pop() {
dumpstackIn();
return stackOut.pop();
}
//获取栈顶元素
public int peek() {
//先确保stackOut不为空
dumpstackIn();
return stackOut.peek();
}
public boolean empty() {
return stackIn.isEmpty()&&stackOut.isEmpty();
}
//如果stackOut变为空之后,就要将stackIn的元素弹出进入stackOut
public void dumpstackIn(){
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.用队列实现栈
题目链接:https://leetcode.cn/problems/implement-stack-using-queues/
思路:
使用两个队列,第一个队列是同栈的出顺序保持一致,而第二个队列是用来辅助存放还未最后出队的内容的。
这题需要看着题解来了解会更好理解,我还不是很能完全理解。
class MyStack {
//用两个队列来理解
Queue<Integer> queue1;
Queue<Integer> queue2;
//queue1是和栈的出顺序保持一致的
public MyStack() {
queue1=new LinkedList<Integer>();
queue2=new LinkedList<Integer>();
}
public void push(int x) {
//先将后出元素放入辅助队列
queue2.offer(x);
while(!queue1.isEmpty()){
queue2.offer(queue1.poll());
}
//最后交换queue1和queue2,将元素都放入queue1中,queue1是与栈保持一致的
Queue<Integer> temp=new Queue<Integer>();
temp=queue1;
queue1=queue2;
queue2=temp;
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty();
}
}
/**
* 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();
*/
20.有效的括号
题目链接:https://leetcode.cn/problems/valid-parentheses/
*括号匹配是使用栈解决的经典问题!!!
*栈特别适合用来做对称匹配类的问题!!!
思路:
本题是经典的“括号匹配问题”,因此利用栈来完成;
给出的字符串是:只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s;要判断括号是否都能匹配,首先观察到这字符串是左右对称的;过程是:创建一个栈,然后遍历字符串,当遍历到无论哪种类型括号的左边,就将当前左边括号对应的右边括号加入到栈中;然后到遍历到右边括号时就看与当前栈顶括号是否相同,若相同就移除此;这里面还需要设置一个条件为:栈为空或者是栈顶括号与当前遍历括号不同,那就说明不匹配返回false;因为这字符串是对称的,所以按照上面过程是能获得结果的;最后返回栈是否为空(isEmpty()),若为空就说明是匹配的。
class Solution {
public boolean isValid(String s) {
Stack<Character> stack=new Stack<Character>();
char ch;
for(int i=0;i<s.length();i++){
ch=s.charAt(i);
if(ch=='('){
stack.push(')');
}else if(ch=='{'){
stack.push('}');
}else if(ch=='['){
stack.push(']');
}else if(stack.isEmpty()||stack.peek()!=ch){
return false;
}else if(stack.peek()==ch){
stack.pop();
}
}
return stack.isEmpty();
}
}
1047.删除字符串中的所有相邻重复项
题目链接:https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/
思路:
首先创建栈,然后遍历字符串,这里设置判断条件,若当前的栈中为空或者栈顶和当前遍历到的字符不同时,则将当前的这个字符push()进栈中;若当前栈不为空且栈顶与当前遍历到的字符相同时,则将当前栈顶pop()出栈;在进行完以上操作,遍历完后,栈只剩下最后的结果,但是这个结果字符串是反的,所以需要设StringBuilder,来将当还不为空时依次pop()出的字符用append方法加入到StringBuilder中;最后返回这个StringBuilder反转后的字符串。
class Solution {
public String removeDuplicates(String s) {
Stack<Character> stack=new Stack<Character>();
char ch;
for(int i=0;i<s.length();i++){
ch=s.charAt(i);
if(stack.isEmpty()||ch!=stack.peek()){
stack.push(ch);
}else{
stack.pop();
}
}
StringBuilder sb=new StringBuilder();
while(!stack.isEmpty()){
char c=stack.pop();
sb.append(c);
}
return sb.reverse().toString();
}
}
今日总结:
对于栈的使用比较熟悉也能独立思考到;但是对于队列还不能掌握,后续需要将使用队列的题拉出做一个专题再学习,225.用队列实现栈归纳到后续需要再理解学习的题目中。