【LeetCode】升级打怪之路 Day 13:优先级队列的应用

news2024/12/26 11:22:04

今日题目:

  • 23. 合并 K 个升序链表 | LeetCode
  • 378. 有序矩阵中第 K 小的元素 | LeetCode
  • 373. 查找和最小的 K 对数字 | LeetCode
  • 703. 数据流中的第 K 大元素 | LeetCode
  • 347. 前 K 个高频元素 | LeetCode

目录

    • Problem 1:合并多个有序链表 【classic】
      • LC 23. 合并 K 个升序链表 ⭐⭐⭐⭐⭐
      • LC 378. 有序矩阵中第 K 小的元素
      • LC 373. 查找和最小的 K 对数字 【略有难度】
    • Problem 2:寻找第 k 个最大元素
      • LC 703. 数据流中的第 K 大元素 【classic】 ⭐⭐⭐⭐⭐
      • LC 347. 前 K 个高频元素 【easy】

优先级队列的特色是动态排序,插入的元素可以自动维护正确的顺序。其限制就是,优先级队列的限制是只能从队头和队尾操作元素。

一般来说,用到优先级队列的题目主要分两类:

  1. 一类是合并多个有序链表这类题
  2. 另一类是寻找第 k 个最大元素这类题

这两类题目都是经典题型,需要理解。

Problem 1:合并多个有序链表 【classic】

有很多题目在使用优先级队列时,解题思路都可以归结于“合并多个有序链表”,这里先学会使用 PriorityQueue 来解决合并多个有序链表的问题,再看看有哪些变形。

LC 23. 合并 K 个升序链表 ⭐⭐⭐⭐⭐

23. 合并 K 个升序链表 | LeetCode

这个题目可以用双指针法,但使用优先级队列更能解决这一大类问题。

这种题的基本思路就是:将每个链表的头节点入队,然后开始迭代,每轮迭代中,从队列中拿出堆顶元素(即最小元素),然后把这个节点的 next 节点入队,进入下一轮迭代。直到合并结束。

这种解题思路很巧妙地运用了各链表“升序”的特点以及优先级队列的好处。

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists.length == 0) {
            return null;
        }
        
        PriorityQueue<ListNode> queue = new PriorityQueue<>(lists.length, (a, b) -> (a.val - b.val));
        ListNode vHead = new ListNode();
        ListNode curr = vHead;

        // 将各链表的头节点放入队列中
        for (var node: lists) {
            if (node != null) {
                queue.offer(node);
            }
        }

        while (!queue.isEmpty()) {
            var min = queue.poll();  // 获取当前堆中最小元素节点
            curr.next = min;
            curr = curr.next;
            if (min.next != null) {
                queue.offer(min.next);
            }
        }

        return vHead.next;
    }
}

LC 378. 有序矩阵中第 K 小的元素

378. 有序矩阵中第 K 小的元素 | LeetCode

这个题是上面“合并 K 个升序链表”的变形题,因为矩阵的每一行都是升序的,可以将矩阵的每一行视为一个升序链表,这样解题思路就与之前的是一样了,难度不大。

LC 373. 查找和最小的 K 对数字 【略有难度】

373. 查找和最小的 K 对数字 | LeetCode

一开始做这个题,没有想到如何使用 PriorityQueue,也没有将这个题转换到“合并 K 个升序链表”这个基本问题的思路上,导致出现多次提交错误。这个题目本质上还是合并 K 个升序链表的变形

这个题目可以这样想象将其转换为 K 个有序链表:将固定一个 nums1[i] 与 nums2 的各个元素进行相加,就可以一串升序的结果。所以每个 nums1 的元素可以按照上面这种方式得到一个链表,那么这个问题就转换为了 nums1.length 个升序链表的合并问题了。

举例子可以参考 labuladong 的讲解:

在这里插入图片描述

想清楚思路之后,难度也就还行了。

Problem 2:寻找第 k 个最大元素

这是 PriorityQueue 的另一个经典应用。直接通过题目来看一下。

LC 703. 数据流中的第 K 大元素 【classic】 ⭐⭐⭐⭐⭐

703. 数据流中的第 K 大元素 | LeetCode

这个题目是经典的利用 PriorityQueue 来寻找第 k 个最大元素的问题。

PriorityQueue 来寻找 Top K 的方法与排序等方法的关键区别在于:只找到 Top K,不排序 Top K

因为如果使用排序法的话,就是对所有元素排序,然后就可以找到 top K 了,但是使用 priority queue 的话,Top K 的 K 个元素的顺序都是可以不用排出来的。

解题思路:

top-k

来源:拜托,面试别再问我TopK了!!!

这里可以得到一个经验:保持小根堆一直为 K 的元素,就可以保证这 K 个元素是一个数据流的最大的 K 的元素,因为比他们小的元素都被 pop 出去了,因为小根堆的顶端是最小元素,所以每次 pop 出去的一定是最小元素。

代码实现:

class KthLargest {

    private int k;

    private PriorityQueue<Integer> heap;

    public KthLargest(int k, int[] nums) {
        this.k = k;
        this.heap = new PriorityQueue<>(k + 1);
        for (int num: nums) {
            heap.offer(num);
            if (heap.size() > k) {
                heap.poll();  // pop 出最小元素
            }
        }
    }
    
    public int add(int val) {
        heap.offer(val);
        while (heap.size() > k) {
            heap.poll();  // pop 出最小元素
        }
        return heap.peek();  // 堆中是最大的 K 个元素,堆顶就是这个 K 个元素中最小的那个,也就是第 K 大的元素
    }
}

LC 347. 前 K 个高频元素 【easy】

347. 前 K 个高频元素 | LeetCode

循环队列的经典应用,难度不大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1490869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一些硬件知识(五)

选择MCU时需要考虑以下几个方面&#xff1a;1。首先考虑引脚功能数量是否够用2.其次如果跑RTOS操作系统的话对堆栈有要求3.需要考虑单片机某个功能的极限性能&#xff0c;例如做BLDC驱动板子的时候要求对电机的电流做到精确采样&#xff0c;此时会选用这个方向表现较好的MCU,例…

如何搭建Nacos集群

1.搭建Nacos集群 众所周知&#xff0c;在实际的工作中&#xff0c;Nacos的生成环境下一定要部署为集群状态 其中包含3个nacos节点&#xff0c;然后一个负载均衡器代理3个Nacos。这里负载均衡器可以使用nginx。 我们计划的集群结构&#xff1a; 我就直接在本机上开三个Nacos来搭…

变分推断中的ELBO(证据下界)

一、变分推断简介 变分推理的目标是近似潜在变量(latent variables)在观测变量(observed variables)下的条件概率。解决该问题,需要使用优化方法。在变分推断中,需要使用到的一个重要理论,是平均场理论。 1、平均场理论 来源于物理学,是一种研究复杂多体问题的方法,将…

Rust 中如何解析 JSON?

Rust 中如何解析 JSON? 在本文中&#xff0c;我们将讨论如何在 Rust 中使用 JSON 解析库&#xff0c;以及比较最流行的库及其性能。 JSON 解析基础知识 手动解析 JSON 要开始在 Rust 中使用 JSON&#xff0c;您需要安装一个可以轻松操作 JSON 的库。目前可用的流行crate之一…

07 系统的线性时不变特性

各位看官&#xff0c;大家好&#xff01;本讲为《数字信号处理理论篇》07 系统的线性时不变特性。&#xff08;特别提示&#xff1a;课程内容为由浅入深的特性&#xff0c;而且前后对照&#xff0c;不要跳跃观看&#xff0c;请按照文章或视频顺序进行观看。 从本讲开始开始为大…

【Python】进阶学习:__len__()方法的使用介绍

【Python】进阶学习&#xff1a;__len__()方法的使用介绍 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订…

shadertoy 游戏《来自星尘》摇杆复刻

正确的做法应该是上 noise 而不是叠加 sin 波&#xff0c;不过如果不想麻烦的话叠波还是一个不错的选择&#xff1a;整体效果如下&#xff0c;已经非常形似 直接上链接&#xff1a;Shader - Shadertoy BETA float radiusScale 0.9; float variation(vec2 v1, vec2 v2, float …

KCV(Key Check Value)的作用(验证密钥导入是否正确)与算法(DES/3DES或AES)示例

KCV的作用与算法 KCV&#xff08;Key Check Value&#xff09;的计算通常与加密算法有关&#xff0c;不同算法计算KCV的方式不同。以下是常见算法的KCV计算方法&#xff1a; DES/3DES算法&#xff1a; KCV是通过使用ECB模式的3DES加密8字节’00’来计算的。例如&#xff0c;…

【鸿蒙 HarmonyOS 4.0】弹性布局(Flex)

一、介绍 弹性布局&#xff08;Flex&#xff09;提供更加有效的方式对容器中的子元素进行排列、对齐和分配剩余空间。容器默认存在主轴与交叉轴&#xff0c;子元素默认沿主轴排列&#xff0c;子元素在主轴方向的尺寸称为主轴尺寸&#xff0c;在交叉轴方向的尺寸称为交叉轴尺寸…

Pipy 进化:从可编程代理到应用引擎

网络功能变得越来越复杂&#xff0c;编写和维护的难度提升&#xff1b;新的基于 Pipy 的应用中&#xff0c;Pipy 角色从数据平面变成控制面&#xff0c;需要执行更多复杂非网络的逻辑&#xff1b;从长远来看&#xff0c;Pipy 将更像是一个常见的类似 shell/bash 的系统脚本工具…

如何在MinIO系统中进行配置并结合内网穿透实现公网远程连接上传文件

文章目录 前言1. 创建Buckets和Access Keys2. Linux 安装Cpolar3. 创建连接MinIO服务公网地址4. 远程调用MinIO服务小结5. 固定连接TCP公网地址6. 固定地址连接测试 前言 MinIO是一款高性能、分布式的对象存储系统&#xff0c;它可以100%的运行在标准硬件上&#xff0c;即X86等…

力扣hot100题解(python版33-35题)

33、排序链表 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4]示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;[-1,0,3,4,5]示例 3&a…

你知道该如何使用 JS 创建 css 类样式吗?

前言 去年我为公司内部开发了一个浏览器插件&#xff0c;当时为了加快开发进度&#xff0c;我没有选用现成的插件框架&#xff0c;而是直接使用原生 JavaScript 搭配 Rollup 进行打包。由于这是一个浏览器插件&#xff0c;我不可避免地需要对页面元素进行操作&#xff0c;比如…

小太阳防倾倒开关原理

小太阳防倾倒开关是一种体积小巧、安装简便、灵敏度高的设备&#xff0c;其原理基于角度感应和光电技术。该开关具有精确的角度判断能力&#xff0c;无需机械接触&#xff0c;稳定性强&#xff0c;支持个性化角度设置&#xff0c;可根据需求进行水平、垂直或倒置安装。 在应用…

注意力机制(代码实现案例)

学习目标 了解什么是注意力计算规则以及常见的计算规则.了解什么是注意力机制及其作用.掌握注意力机制的实现步骤. 1 注意力机制介绍 1.1 注意力概念 我们观察事物时&#xff0c;之所以能够快速判断一种事物(当然允许判断是错误的), 是因为我们大脑能够很快把注意力放在事物…

STM32(16)使用串口向电脑发送数据

发送字节 发送数组 发送字符和字符串 字符&#xff1a; 字符串&#xff1a; 字符串在电脑中以字符数组的形式存储

最新AI系统ChatGPT网站H5系统源码,支持Midjourney绘画

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

《互联网的世界》第四讲-拥塞控制与编码

需要澄清的一个误区是&#xff0c;拥塞绝不是发送的数据量太大导致&#xff0c;而是数据在极短的时间段内到达了同一个地方以至于超过了网络处理容量导致&#xff0c;拥塞的成因一定要考虑时间因素。换句话说&#xff0c;拥塞由大突发导致。 只要 pacing&#xff0c;再多的数据…

MongoDB开启事务

MongoDB开启事务 配置单节点。到路径C:\Program Files\MongoDB\Server\4.0\bin 使用记事本以管理员权限打开文件mongod.cfg添加如下配置&#xff1a; replication:replSetName: rs02. 重启MongoDB服务 3. 重启后执行命令 rs.initiate()

Python采集学习笔记-request的get请求和post请求

使用http://httpbin.org测试,一个简单的 HTTP 请求和响应服务。(需联网)1.导入requests包 import requests 2.测试get请求 url http://httpbin.org/get par {key1: value1, key2: value2} # 不带参数请求 r1 requests.get(url) # 带参数请求 r2 requests.get(url, paramspa…