代码随想录五刷day5

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • [一、力扣232. 用栈实现队列](#一、力扣232. 用栈实现队列)
  • [二、力扣225. 用队列实现栈](#二、力扣225. 用队列实现栈)
  • [三、力扣20. 有效的括号](#三、力扣20. 有效的括号)
  • [四、力扣1047. 删除字符串中的所有相邻重复项](#四、力扣1047. 删除字符串中的所有相邻重复项)
  • [五、力扣150. 逆波兰表达式求值](#五、力扣150. 逆波兰表达式求值)
  • [六、力扣239. 滑动窗口最大值](#六、力扣239. 滑动窗口最大值)
  • [七、力扣前 K 个高频元素](#七、力扣前 K 个高频元素)

前言


在栈与队列系列中,我们强调栈与队列的基础,也是很多同学容易忽视的点。 使用抽象程度越高的语言,越容易忽视其底层实现,而C++相对来说是比较接近底层的语言。 我们用栈实现队列,用队列实现栈来掌握的栈与队列的基本操作。

一、力扣232. 用栈实现队列

java 复制代码
class MyQueue {
    private Deque<Integer> d1;
    private Deque<Integer> d2;

    public MyQueue() {
        this.d1 = new LinkedList<>();
        this.d2 = new LinkedList<>();
    }
    
    public void push(int x) {
        d1.offerLast(x);
    }
    
    public int pop() {
        if(!d2.isEmpty()){
            return d2.pollLast();
        }
        while(!d1.isEmpty()){
            d2.offerLast(d1.pollLast());
        }
        return d2.pollLast();
    }
    
    public int peek() {
        if(!d2.isEmpty()){
            return d2.peekLast();
        }
        while(!d1.isEmpty()){
            d2.offerLast(d1.pollLast());
        }
        return d2.peekLast();
    }
    
    public boolean empty() {
        return d1.isEmpty() && d2.isEmpty();
    }
}

二、力扣225. 用队列实现栈

java 复制代码
class MyStack {
    Deque<Integer> d1 = new LinkedList<>();
    Deque<Integer> d2 = new LinkedList<>();

    public MyStack() {
        
    }
    
    public void push(int x) {
        d1.offerLast(x);
    }
    
    public int pop() {
        if(!d1.isEmpty()){
            while(d1.size() > 1){
                d2.offerLast(d1.pollFirst());
            }
            return d1.pollFirst();
        }
        while(d2.size() > 1){
            d1.offerLast(d2.pollFirst());
        }
        return d2.pollFirst();
    }
    
    public int top() {
        if(!d1.isEmpty()){
            while(d1.size() > 1){
                d2.offerLast(d1.pollFirst());
            }
            return d1.peekFirst();
        }
        while(d2.size() > 1){
            d1.offerLast(d2.pollFirst());
        }
        int res = d2.pollFirst();
        d1.offerLast(res);
        return res;
    }
    
    public boolean empty() {
        return d1.isEmpty() && d2.isEmpty();
    }
}

三、力扣20. 有效的括号

java 复制代码
class Solution {
    public boolean isValid(String s) {
        Deque<Character> deq = new LinkedList<>();
        for(char c : s.toCharArray()){
            if(c == '[' || c == '(' || c == '{'){
                deq.offerLast(c);
            }else{
                if(deq.isEmpty()){
                    return false;
                }
                char t = deq.pollLast();
                if(c == ')' && t != '('){
                    return false;
                }
                if(c == ']' && t != '['){
                    return false;
                }
                if(c == '}' && t != '{'){
                    return false;
                }
            }
        }
        return deq.isEmpty();
    }
}

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

java 复制代码
class Solution {
    public String removeDuplicates(String s) {
        Deque<Character> deq = new LinkedList<>();
        for(char c : s.toCharArray()){
            if(deq.isEmpty()){
                deq.offerLast(c);
                continue;
            }
            if(deq.peekLast() == c){
                deq.pollLast();
                continue;
            }
            deq.offerLast(c);
        }
        StringBuilder sb = new StringBuilder();
        while(!deq.isEmpty()){
            sb.append(deq.pollFirst());
        }
        return sb.toString();
    }
}

五、力扣150. 逆波兰表达式求值

java 复制代码
class Solution {
    public int evalRPN(String[] tokens) {
        Deque<Integer> deq = new LinkedList<>();
        int l  = 0, r = 0;
        for(String s : tokens){
            if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")){
                r = deq.pollLast();
                l = deq.pollLast();
                switch (s){
                    case "+" : deq.offerLast(l + r);break;
                    case "-" : deq.offerLast(l - r);break;
                    case "*" : deq.offerLast(l * r);break;
                    case "/" : deq.offerLast(l / r);break;
                }
            }else{
                System.out.println(s);
                deq.offerLast(Integer.parseInt(s));
            }
        }
        return deq.pollLast();
    }
}

六、力扣239. 滑动窗口最大值

滑动窗口中的最大值,首先维护一个单调队列,这题要求最大值,所以维护的是一个出队方向最大的一个单调队列,对于每一个元素来说,轮到他时,就要判断一下,队列头的元素是不是在窗口内的,不是的要抛出,然后就是维护队列的逻辑,判断队列是否非空,空的话直接加入,非空的话,从队尾方向,把小于当前元素的都抛出,最后把自己维护进去,然后是收集逻辑,因为是窗口的最大值,所以一开始,当前元素未移动到窗口的最后一个,不做收集

java 复制代码
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        Deque<Integer> deq = new LinkedList<>();
        List<Integer> res = new ArrayList<>();
        for(int i = 0; i < nums.length; i ++){
            if(!deq.isEmpty() && deq.peekFirst() <= i-k){
                deq.pollFirst();
            }
            if(deq.isEmpty()){
                deq.offerLast(i);
            }else{
                while(!deq.isEmpty() && nums[i] > nums[deq.peekLast()]){
                    deq.pollLast();
                }
                deq.offerLast(i);
            }
            if(i >= k-1){
                res.add(nums[deq.peekFirst()]);
            }
        }
        int[] array = res.stream().mapToInt(Integer::intValue).toArray();
        return array;
    }
}

七、力扣前 K 个高频元素

获取前K个高频元素,可以先用map收集各个元素的频率,然后使用优先级队列,大根堆进行收集,最后抛出前K个元素

java 复制代码
class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer,Integer> map = new HashMap<>();
        int[] res = new int[k];
        for(int n : nums){
            map.put(n, map.getOrDefault(n,0) + 1);
        }
        PriorityQueue<int[]> pq = new PriorityQueue<>((x1,x2) -> x2[1] - x1[1]);
        for(Map.Entry<Integer,Integer> entry : map.entrySet()){
            pq.add(new int[]{entry.getKey(),entry.getValue()});
        }
        for(int i = 0; i < k; i ++){
            res[i] = pq.poll()[0];
        }
        return res;
    }
}
相关推荐
To_OC6 小时前
LC 49 字母异位词分组:想到哈希表很简单,选对 key 才是精髓
javascript·算法·leetcode
小bo波9 小时前
使用Thread子类创建线程 VS 使用Runnable接口创建线程的区别
java·多线程·thread·并发编程·runnable
SamDeepThinking10 小时前
高并发场景下,CompletableFuture与ForkJoinPool该如何取舍?
java·后端·面试
用户9385156350711 小时前
从 O(n²) 到 O(nlogn):一文读懂快速排序的“快”与“妙”
javascript·算法
To_OC12 小时前
手写快排次次翻车?别死背快排模板了,这才是面试官想听的底层逻辑
javascript·算法·排序算法
饼干哥哥12 小时前
Reddit VOC调研太慢?搭一个AI专家团队半小时洞察任何品类|以猫用饮水机为例
人工智能·算法·ai编程
张不才13 小时前
CPU 100% 了怎么办?Java 性能排障的标准化操作
java·后端
地平线开发者14 小时前
Transformer模型部署之性能优化指南
算法
地平线开发者14 小时前
人在途中:从“编译失败”到“模型可落地”——CUDA 自定义算子
算法·自动驾驶
shepherd11114 小时前
吞吐量提升 10 倍:高并发大批量数据处理任务的架构演进与性能调优
java·后端·架构