力扣23. 合并 K 个升序链表(java,最小堆解法)

Problem: 23. 合并 K 个升序链表

文章目录

  • 题目描述
  • 思路
  • 解题方法
  • 复杂度
  • Code

题目描述

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。
在这里插入图片描述
在这里插入图片描述

思路

1.对于合并k个有序链表,我们较为容易想到的是用k个指针指向k个链表再依次比较每个指针当前指向节点的值的大小再进行接下来的拼接操作,分析易得这种方法的时间复杂度为 O ( k n ) O(kn) O(kn)
2.我们容易注意到上述主要的操作是每次比较并移动指针,且移动的是当前指向节点的值为最小的指针,基于以上特点我们可以想到利用最小堆来完成该操作。

解题方法

1.编写内部类QElement。后续创建的最小堆中存储的为指针类型的变量
2.创建最小堆,起初将每个链表头节节点添加进去生成一个最小堆
3.创建虚拟头节点和尾指针以便生成结果链表
4.当最小堆不为空时,每次取出堆顶元素(为ListNode类型指针)当栈顶元素的next指针不为空时,将其next指针指向的节点再次添加到最小堆中,生成一个新的最小堆。

复杂度

时间复杂度:

O ( k l o g n ) O(klogn) O(klogn)

空间复杂度:

O ( k ) O(k) O(k)

Code

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    private class QElement {
        ListNode curNode;

        public QElement(ListNode curNode) {
            this.curNode = curNode;
        }
    }

    /**
     * 利用小顶堆合并k个升序链表
     *
     * @param lists 链表头节点数组
     * @return ListNode
     */
    public ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) {
            return null;
        }
        int len = lists.length;
        ;
        //创建小顶堆
        PriorityQueue<QElement> minQueue = new PriorityQueue<>(new Comparator<QElement>() {
            @Override
            public int compare(QElement o1, QElement o2) {
                return o1.curNode.val - o2.curNode.val;
            }
        });
        //将链表加入到小顶堆
        for (int i = 0; i < len; ++i) {
            if (lists[i] != null) {
                minQueue.offer(new QElement(lists[i]));
            }
        }
        //创建虚拟头节点
        ListNode dummyNode = new ListNode();
        ListNode tail = dummyNode;
        //当小顶堆不为空时,每次取出堆顶元素添加到结果链表
        while (!minQueue.isEmpty()) {
            QElement element = minQueue.poll();
            ListNode curNode = element.curNode;
            tail.next = element.curNode;
            tail = tail.next;
            //当前指针(已经移动后的指针)指向的的下一位不为空
            if (curNode.next != null) {
                minQueue.offer(new QElement(curNode.next));
            }
        }
        return dummyNode.next;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java —— 泛型

目录 1. 什么是泛型 2. 泛型背景及其语法规则 3. 泛型类的使用 3.1 语法 3.2 示例 3.3 类型推导(Type Inference) 4. 裸类型(Raw Type) 4.1 说明 5. 泛型如何编译的 5.1 擦除机制 5.2 为什么不能实例化泛型类型数组 6. 泛型的上界 6.1 上界语法产生的背景 6.2 语法 6.3 示例 6.…

Node.js入门指南(完结)

目录 接口 介绍 RESTful json-server 接口测试工具 会话控制 介绍 cookie session token 上一篇文章我们介绍了MongoDB&#xff0c;这一篇文章是Node.js入门指南的最后一篇啦&#xff01;主要介绍接口以及会话控制。 接口 介绍 接口是前后端通信的桥梁 &#xff0…

elk日志分析系统:

elk日志分析系统: elk是一套完整的日志集中处理方案&#xff0c;由三个开源的软件简称组成&#xff1b; E:Easticsearch 简称ES是一个开源的&#xff0c;分布式的存储检索引擎&#xff0c;&#xff08;索引型的非关系数据库&#xff09;存储日志 由java代码开发的&#xff0…

麒麟V10桌面搭建FTP服务

1.1介绍 FTP&#xff1a;File transfer protocol &#xff08;文件传输协议&#xff09;是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分&#xff0c;其一为FTP服务器&#xff0c;其二为FTP客户端。其中FTP服务器用来存储文件&#xff0c;用户可以使用FTP客户端通过FT…

知识变现的未来:解析知识付费系统的核心

随着数字时代的发展&#xff0c;知识付费系统作为一种新兴的学习和知识分享模式&#xff0c;正逐渐引领着知识变现的未来。本文将深入解析知识付费系统的核心技术&#xff0c;揭示其在知识经济时代的重要性和潜力。 1. 知识付费系统的基本架构 知识付费系统的核心在于其灵活…

CorelDRAW Graphics Suite2023破解版含2024最新注册机下载

CorelDRAW Graphics Suite2023是Corel公司的平面设计软件&#xff1b;该软件是Corel出品的矢量图形制作工具软件&#xff0c;这个图形工具给设计师提供了矢量动画、页面设计、网站制作、位图编辑和网页动画等多种功能。在日常科研绘图中&#xff0c;若较为轻量&#xff0c;通常…

【Linux进阶之路】进程间通信

文章目录 一、原理二、方式1.管道1.1匿名管道1.1.1通信原理1.1.2接口使用 1.2命名管道 2.共享内存2.1原理2.2接口使用 3.消息队列原理 4.信号量引入原理 总结 一、原理 进程间的通信是什么&#xff1f;解释&#xff1a; 简单理解就是&#xff0c;不同进程之间进行数据的输入输出…

使用Tensorboard可视化 遇到无法访问此网站

问题&#xff1a; 使用Tensorboard可视化 遇到无法访问此网站 解决方法&#xff1a;后面加上服务器ip[参考] tensorboard --logdir目标目录 --hostxxx.xxx.xxx.xx

[学习记录]Node event loop 总结流程图

文章目录 文章来源根据内容输出的流程图待处理遗留的问题参考 文章来源 详解JavaScript中的Event Loop&#xff08;事件循环&#xff09;机制 根据内容输出的流程图 待处理 这里从polling阶段开始 好像有些问题 遗留的问题 为什么“在I/O事件的回调中&#xff0c;setImmediate…

Docker | 自定义Docker镜像

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;Docker系列 ✨特色专栏&#xff1a; My…

AB|如何正确从罗克韦尔官网下载资料?

哈喽呀&#xff0c;大家好&#xff0c;我是雷工&#xff01; 作为工控行业的从业者&#xff0c;可能要和各个厂家的中控系统、PLC、触摸屏、变频器、等软硬件产品打交道。 虽然从业十余年&#xff0c;但也不可能接触使用过所有的工控产品。还有海量的产品是没有接触过的。 但很…

sql注入靶场

第一关&#xff1a; 输入&#xff1a;http://127.0.0.1/sqli-labs-master/Less-1/?id1 http://127.0.0.1/sqli-labs-master/Less-1/?id1%27 http://127.0.0.1/sqli-labs-master/Less-1/?id1%27-- 使用--来闭合单引号&#xff0c;证明此处存在字符型的SQL注入。 使用order …

5.27每日一题(判断函数在那个区间上有界:充分条件不是必要条件)

若f(x)在(a , b)上连续&#xff0c;且f(a0)&#xff0c;f&#xff08;b-0&#xff09;存在&#xff08;及函数的左右极限存在&#xff09;>f(x)在(a,b)上有界

springboot中4级配置文件优先级

springboot中4级配置文件优先级

【AICFD案例教程】PCB多变量AI预测分析

AICFD是由天洑软件自主研发的通用智能热流体仿真软件&#xff0c;用于高效解决能源动力、船舶海洋、电子设备和车辆运载等领域复杂的流动和传热问题。软件涵盖了从建模、仿真到结果处理完整仿真分析流程&#xff0c;帮助工业企业建立设计、仿真和优化相结合的一体化流程&#x…

【视觉SLAM十四讲学习笔记】第三讲——四元数

专栏系列文章如下&#xff1a; 【视觉SLAM十四讲学习笔记】第一讲——SLAM介绍 【视觉SLAM十四讲学习笔记】第二讲——初识SLAM 【视觉SLAM十四讲学习笔记】第三讲——旋转矩阵 【视觉SLAM十四讲学习笔记】第三讲——Eigen库 【视觉SLAM十四讲学习笔记】第三讲——旋转向量和欧…

【小白进阶】Linux 调试大法——gdb

初衷 gdb调试是每一个后端开发工程师所必备的技能&#xff0c;我们工作总是会用gdb协助我们去分析和调试问题。但是大部分同学的技能仅停留在最基础的查看问题。即gdb program -->r --> 问题复现 --> bt 查看源码中的哪一行出现了错误。再稍微熟练点的&#xff0c;可能…

Node.js 事件循环:定时任务、延迟任务和 I/O 事件的艺术

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

python多线程和多进程

1.多线程 线程是程序执行的最小单位&#xff0c;一个进程至少有一个线程。 提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。 进程之间不能共享内存&#xff0c;但线程之间共享内存非常容易。 Python 常用的多线程库有threading 和…