代码随想录之栈和队列(力扣题号)
创始人
2025-05-29 07:40:40

232 用栈实现队列

在这里插入图片描述

class MyQueue {//12-24Stack s1 = new Stack<>();Stack s2 = new Stack<>();int size;public MyQueue() {size = 0;}public void push(int x) {s1.push(x);size++;}public int pop() {for(int i=0;is2.push(s1.pop());}size--;int res = s2.pop();//最后要保证数据都在s1里for(int i=0;is1.push(s2.pop());}return res;}public int peek() {for(int i=0;is2.push(s1.pop());}int res = s2.peek();//最后要保证数据都在s1里for(int i=0;is1.push(s2.pop());}return res;}public boolean empty() {if(size==0) return true;else return false;}
}/*** 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();*/

思路很简单,就是用栈s1存,然后要取值再全部倒到s2,中。一开始没过是因为pop和peek完没有再把s2中得数据倒到s1中。

觉得我这种写法还是不简洁,再pop和peek的操作中有大量重复的,而且不一定每次都要让所有元素都在s1里,每次pop的时候如果s1有元素,直接pops1里的,如果没有再倒元素过去,更新了一下更简洁的代码

class MyQueue {Stack in = new Stack<>();Stack out = new Stack<>();public MyQueue() {}public void push(int x) {in.push(x);}public int pop() {dumpStackIn();return out.pop();}public int peek() {dumpStackIn();return out.peek();}public boolean empty() {return in.empty()&&out.empty();}public void dumpStackIn(){if(!out.empty()) return;while(!in.empty()){out.push(in.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 用队列实现栈

在这里插入图片描述

在这里插入图片描述

本来以为和上一题是一样的,写完才发现不对劲,因为队列一直是先进先出,用几个队列倒过来倒过去都不会改变数据的顺序,所以用一个队列就够了。
只要让每次push进来的元素都处于队列的头即可。

class MyStack {Queue q = new LinkedList<>();public MyStack() {}public void push(int x) {q.offer(x);int size = q.size();//让每次新进来的元素都处于队列的头,其他的元素放到末尾,一个队列本身就能实现while(size-- >1){q.offer(q.poll());}}public int pop() {return q.poll();}public int top() {return q.peek();}public boolean empty() {return q.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 有效的括号

在这里插入图片描述
很简单,经典的用栈的做法,只要判断是不是左括号多,或者右括号多,或者和栈顶是否匹配即可

class Solution {public boolean isValid(String s) {//53-59Stack st = new Stack<>();for(int i=0;iif(s.charAt(i)=='('||s.charAt(i)=='{'||s.charAt(i)=='['){st.push(s.charAt(i));}else if(st.empty()) return false;//右括号多else if(s.charAt(i)==')'&&st.pop()!='(') return false;else if(s.charAt(i)==']'&&st.pop()!='[') return false;else if(s.charAt(i)=='}'&&st.pop()!='{') return false;            }if(!st.empty()) return false;//左括号多return true;}
}

1047. 删除字符串中的所有相邻重复项

在这里插入图片描述

class Solution {public String removeDuplicates(String s) {//10Stack st = new Stack();// st.push(s.charAt(0));for(int i=0;iif(st.empty()||s.charAt(i)!=st.peek()) st.push(s.charAt(i));else st.pop();}StringBuilder res = new StringBuilder();while(!st.empty()){res.append(st.pop());}res.reverse();return res.toString();    }
}

看了题解之后发现其实不用定义Stack,直接用stringBuilder

150. 逆波兰表达式求值

class Solution {public int evalRPN(String[] tokens) {//56-10Stack s = new Stack<>();for(int i=0;iif(tokens[i].equals("+")||tokens[i].equals("-")||tokens[i].equals("*")||tokens[i].equals("/")){int b = s.pop();int a = s.pop();switch(tokens[i]){case "+":{s.push(a+b);break;}case "-":{s.push(a-b);break;}case "*":{s.push(a*b);break;}case "/":{s.push(a/b);break;}}}else s.push(Integer.parseInt(tokens[i]));}return s.pop();}
}

比表达式求值简单多了,只要判断来了运算符,就从栈里pop出两个元素出来计算,先入栈的那个元素是第一个数字,在-和/的时候要注意。第一次写踩的坑是case没有break,导致下面的case即使不满足也计算了,记得要写break!或者不熟练直接用if更简洁。

239 滑动窗口的最大值

在这里插入图片描述

因为写过一次,只记得用双端队列,但是具体怎么做还是忘了,总的思想就是每次从右边进队列的时候要把队列中的右边的元素比当前元素小的都poll出去,因为他们再也用不到了,这样维护出来的队列是非递增的,只要再从队头判断下标在窗口内的就可以

class Solution {public int[] maxSlidingWindow(int[] nums, int k) {//45ArrayDeque q = new ArrayDeque();//     ArrayList list = new ArrayList();int[] res = new int[nums.length-k+1];int index = 0;for(int i = 0;i//把队尾的小于当前元素的都pollwhile(!q.isEmpty()&&nums[q.peekLast()]=k)//list.add(nums[q.peekFirst()]);res[index++] = nums[q.peekFirst()];}// int[] res = new int[list.size()];// for(int i=0;i//     res[i] = list.get(i);// }return res;}
}

值得注意的是一直习惯用list存,然后再用int数组倒过来,但是这题可以明确知道结果数组的长度,所以可以直接用int数组,而不用再开list

347 前K个高频元素

疯狂打星号
在这里插入图片描述
第一反应就是用map存频率,然后对map的value排序,发现不知道怎么排序,而且这样的时间复杂度是O(nlogn)不符合要求。思路是用优先队列!用小顶堆,每次进来一个新元素判断和堆顶(最小的)谁大,如果大于堆顶就offer进来,把堆顶poll出去
set的遍历还是要注意!!优先队列存一个数组就行!用map就写得很复杂

class Solution {public int[] topKFrequent(int[] nums, int k) {//44//map 存 然后对value排序Map p = new HashMap<>();for(int i=0;ip.put(nums[i],p.getOrDefault(nums[i],0)+1);}//PriorityQueue> pq = new PriorityQueue<>((a, b) -> a.getValue() - b.getValue());PriorityQueue pq = new PriorityQueue<>((pair1,pair2)->pair1[1]-pair2[1]);for(Map.Entry entry:p.entrySet()){if(pq.size()entry.getKey(),entry.getValue()});else{if(pq.peek()[1]pq.poll();pq.offer(new int[]{entry.getKey(),entry.getValue()});}}}int[] res = new int[k];//poll()顺序出来的是从小到大for(int i=k-1;i>=0;i--){res[i] = pq.poll()[0];}return res;}
}

优先队列插入和删除的时间复杂度是(logk)k是队列里的元素数量,

相关内容

热门资讯

分享实测“中至吉安麻将可以开挂... 您好:中至吉安麻将这款游戏可以开挂,确实是有挂的,需要软件加微信【8700483】,很多玩家在中至吉...
强势揭幕“同乡游麻将是不是有挂... 同乡游麻将这个游戏其实有挂的,确实是有挂的,需要了解加客服微信【38-47-338】或【953-25...
实测推荐“浙江游戏大厅作弊软件... 您好:浙江游戏大厅这款游戏可以开挂,确实是有挂的,需要了解加客服微信【6676724】很多玩家在这款...
玩家必看“琼戏互娱透视软件辅助... 您好:琼戏互娱这款游戏可以开挂,确实是有挂的,需要软件加微信【4194432】,很多玩家在琼戏互娱这...
分享实测“新西部其实有透视辅助... 您好:新西部这款游戏可以开挂,确实是有挂的,需要软件加微信【8700483】,很多玩家在新西部这款游...