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

文章目录

一. 力扣 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();
        }
    }
相关推荐
比奇堡裤头村8 小时前
统计学习方法——决策树
算法·决策树·学习方法
灵晔君8 小时前
【Linux】进程控制(一)——进程创建、进程终止与进程等待
linux·c语言·算法
数模竞赛Paid answer17 小时前
2026年中青杯数学建模A题数学建模论文智能评估系统与多智能体优化方法求解全过程论文及程序
算法·数学建模·中青杯
银-豆豆18 小时前
数据结构与算法-动态规划、回溯与贪心
算法·动态规划
想吃火锅100519 小时前
【leetcode】200. 岛屿数量
算法·leetcode·职场和发展
hold?fish:palm19 小时前
24 回文链表
数据结构·c++·链表
Nil20820 小时前
leetcode 54螺旋矩阵
算法·leetcode·矩阵
依然鸣21 小时前
PTA团体程序设计天梯赛L1真题讲解L1-077-080
开发语言·c++·算法·深度优先·pat考试·图论
qeen871 天前
【数据结构】自平衡二叉搜索树各种旋转算法原理解析及AVL树的C++实现
数据结构·c++·算法
lucas_AI1 天前
1.2B 小模型赢过 235B 大模型:NaviDC-OCR 把文档解析卷明白了
人工智能·深度学习·算法