算法奇妙屋(十二)-优先级队列(堆)

文章目录

一. 力扣 1046. 最后一块石头的重量

1. 题目

2. 算法原理

这道题的算法原理十分简单, 直接建立大根堆即可, 这里简单梳理下

3. 代码

java 复制代码
    public int lastStoneWeight(int[] stones) {
        PriorityQueue<Integer> queue = new PriorityQueue<>((a,b) -> b - a);
        for (int x : stones) {
            queue.offer(x);
        }
        while (queue.size() > 1) {
            int max1 = queue.poll();
            int max2 = queue.poll();
            if (max1 > max2) {
                queue.offer(max1 - max2);
            }
        }
        if (!queue.isEmpty()) {
            return queue.poll();
        }else {
            return 0;
        }
    }

二. 力扣 703. 数据流中的第 K 大元素

1. 题目

题目意思简单易懂, 这里不过多赘述, 直接看图即可

2. 算法原理

这道题有点绕口, 这里我们在初始化类的时候先求出来topk, 然后在后台调用add方法的时候, 只需要重复求topk流程即可, 下面图片解析的是求topk问题时,应该建立哪种类型的堆, 为什么要建这种堆?

3. 代码

java 复制代码
    PriorityQueue<Integer> q;
    int t_k;

    public KthLargest(int k, int[] nums) {
        q = new PriorityQueue<>();
        t_k = k;
        for (int x : nums) {
            q.offer(x);
            if (q.size() > t_k) {
                q.poll();
            }
        }
    }

    public int add(int val) {
        q.offer(val);
        if (q.size() > t_k) {
            q.poll();
        }
        return q.peek();
    }

三. 力扣 692. 前K个高频单词

1. 题目

2. 算法原理

这道题原理不难, 难的是如何将代码实现, 注意掌握Pair的特性

3. 代码

java 复制代码
    public List<String> topKFrequent(String[] words, int k) {
        Map<String, Integer> hash = new HashMap<>();
        for (String s : words) {
            hash.put(s, hash.getOrDefault(s, 0) + 1);
        }
        PriorityQueue<Pair<String, Integer>> q = new PriorityQueue<>(
                (a, b) -> {
                    if (a.getValue().equals(b.getValue())) {
                        return b.getKey().compareTo(a.getKey());
                    }else {
                        return a.getValue() - b.getValue();
                    }
                }
        );
        for (Map.Entry<String, Integer> e : hash.entrySet()) {
            q.offer(new Pair<>(e.getKey(), e.getValue()));
            if (q.size() > k) {
                q.poll();
            }
        }
        List<String> ret = new ArrayList<>();
        while (!q.isEmpty()) {
            ret.add(q.poll().getKey());
        }
        Collections.reverse(ret);
        return ret;
    }

四. 力扣 295. 数据流的中位数

1. 题目

题目就是让求中位数, 最后结果需要注意是double类型

2. 算法原理

(1) 我们这里采用大小堆的解法, 下面我们来解释什么是大小堆

(2)一些细节问题, 例如如何入堆?如何维护顺序排列的数据流?

3. 代码

java 复制代码
    PriorityQueue<Integer> left;
    PriorityQueue<Integer> right;

    public MedianFinder() {
        left = new PriorityQueue<>((a, b) -> b - a);
        right = new PriorityQueue<>();
    }

    public void addNum(int num) {
        int m = left.size();
        int n = right.size();
        Integer x = left.peek();
        if (m == n) {
            if (x == null) {
                left.offer(num);
            } else if (num <= x) {
                left.offer(num);
            } else {
                right.offer(num);
                left.offer(right.poll());
            }
        } else {
            if (num <= x) {
                left.offer(num);
                x = left.poll();
                right.offer(x);
            }else {
                right.offer(num);
            }
        }

    }

    public double findMedian() {
        if (left.size() == right.size()) {
            return (left.peek() + right.peek()) / 2.0;
        }else {
            return left.peek();
        }
    }
相关推荐
无极低码2 小时前
ecGlypher新手安装分步指南(标准化流程)
人工智能·算法·自然语言处理·大模型·rag
软件算法开发2 小时前
基于海象优化算法的LSTM网络模型(WOA-LSTM)的一维时间序列预测matlab仿真
算法·matlab·lstm·一维时间序列预测·woa-lstm·海象优化
罗超驿3 小时前
独立实现双向链表_LinkedList
java·数据结构·链表·linkedlist
superior tigre3 小时前
22 括号生成
算法·深度优先
努力也学不会java4 小时前
【缓存算法】一篇文章带你彻底搞懂面试高频题LRU/LFU
java·数据结构·人工智能·算法·缓存·面试
旖-旎4 小时前
二分查找(x的平方根)(4)
c++·算法·二分查找·力扣·双指针
ECT-OS-JiuHuaShan5 小时前
朱梁万有递归元定理,重构《易经》
算法·重构
智者知已应修善业5 小时前
【51单片机独立按键控制数码管移动反向,2片74CH573/74CH273段和位,按键按下保持原状态】2023-3-25
经验分享·笔记·单片机·嵌入式硬件·算法·51单片机
khddvbe6 小时前
C++并发编程中的死锁避免
开发语言·c++·算法
C羊驼6 小时前
C语言:两天打鱼,三天晒网
c语言·经验分享·笔记·算法·青少年编程