Leetcode 合并 K 个升序链表

java 复制代码
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists == null || lists.length == 0) {
            return null;
        }
        PriorityQueue<ListNode> pq = new PriorityQueue<>((a, b) -> a.val - b.val);
        for(ListNode node:lists) {
            if(node != null) {
                pq.add(node);//将每个链表的第一个节点插入到优先队列中,
                //插入过程中优先队列会按照定义的优先级自动调整插入位置
            }
        }
        ListNode dummy = new ListNode(0);
        ListNode current = dummy;
        while(!pq.isEmpty()) {
           ListNode node = pq.poll();//最小的节点
           current.next = node;
           current = current.next;

           if(node.next != null) {
                pq.add(node.next);
           }
        }
        return dummy.next;
        
    }
}

这段代码的算法思想如下:

算法概述

题目要求合并 ( K ) 个已经升序排列的链表,输出一个合并后的有序链表。代码使用**优先队列(PriorityQueue)**来实现,以确保每次取出当前最小的节点,这样可以高效地合并多个链表。

具体步骤

  1. 初始化优先队列

    • 代码中使用了一个优先队列(最小堆),用于存储链表中的节点。由于 Java 的 PriorityQueue 默认是最小堆,存入的节点会按从小到大的顺序排列。
    • 优先队列的比较方式为 a.val - b.val,即按节点的值进行升序排序。
  2. 将每个链表的头节点加入优先队列

    • 对于传入的每个链表,将其头节点加入优先队列。这样,优先队列中会保存每个链表的第一个节点,代表各个链表的最小值。
    • 如果链表为空,则跳过该链表。
  3. 构建合并后的链表

    • 创建一个虚拟头节点(dummy node) ,目的是简化链表的构建过程,并最终返回 dummy.next 作为结果链表的头节点。
    • 然后通过一个指针 current 来指向新链表的尾部节点,从而逐步构建合并后的链表。
  4. 合并过程

    • 循环从优先队列中取出最小的节点,将其连接到合并链表的尾部。
    • 如果取出的节点有下一个节点,则将这个下一个节点加入优先队列,以确保优先队列中始终包含来自各链表的最小值节点。
    • 重复上述过程,直到优先队列为空。
  5. 返回结果

    • 最后,返回 dummy.next,即合并后的有序链表的头节点。

时间复杂度

该算法的时间复杂度为 ( O(N \log K) ):

  • ( N ) 是所有链表节点的总数。
  • ( K ) 是链表的数量。
  • 由于每次插入和取出优先队列中的元素的时间复杂度是 ( O(\log K) ),整个过程需要 ( N \log K ) 的时间复杂度。

总结

这段代码通过优先队列实现了多链表的高效合并,每次从优先队列中取出最小节点并连接到结果链表上,从而保证了结果链表的有序性。这样就可以在相对较低的时间复杂度下完成 ( K ) 个有序链表的合并。

相关推荐
猎板PCB厚铜专家大族8 分钟前
高频 PCB 技术发展趋势与应用解析
人工智能·算法·设计规范
dying_man19 分钟前
LeetCode--24.两两交换链表中的结点
算法·leetcode
yours_Gabriel19 分钟前
【力扣】2434.使用机器人打印字典序最小的字符串
算法·leetcode·贪心算法
草莓熊Lotso1 小时前
【数据结构初阶】--算法复杂度的深度解析
c语言·开发语言·数据结构·经验分享·笔记·其他·算法
KyollBM1 小时前
【CF】Day75——CF (Div. 2) B (数学 + 贪心) + CF 882 (Div. 2) C (01Trie | 区间最大异或和)
c语言·c++·算法
CV点灯大师1 小时前
C++算法训练营 Day10 栈与队列(1)
c++·redis·算法
GGBondlctrl2 小时前
【leetcode】递归,回溯思想 + 巧妙解法-解决“N皇后”,以及“解数独”题目
算法·leetcode·n皇后·有效的数独·解数独·映射思想·数学思想
武子康2 小时前
大数据-276 Spark MLib - 基础介绍 机器学习算法 Bagging和Boosting区别 GBDT梯度提升树
大数据·人工智能·算法·机器学习·语言模型·spark-ml·boosting
武子康2 小时前
大数据-277 Spark MLib - 基础介绍 机器学习算法 Gradient Boosting GBDT算法原理 高效实现
大数据·人工智能·算法·机器学习·ai·spark-ml·boosting