【数据结构-堆】【hard】力扣23. 合并 K 个升序链表

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

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = \[1,4,5,1,3,4,2,6]

输出:1,1,2,3,4,4,5,6

解释:链表数组如下:

1-\>4-\>5, 1-\>3-\>4, 2-\>6

将它们合并到一个有序链表中得到。

1->1->2->3->4->4->5->6

示例 2:

输入:lists = \[\]

输出:\[\]

示例 3:

输入:lists = \[]

输出:\[\]

优先队列

csharp 复制代码
//正常情况优先队列如果true,表示当前元素比右侧元素小,将右侧元素放到堆顶,实现大根堆。
//改变operator后,当前元素比右侧元素大堆时候true,将右侧元素放到堆顶,实现小根堆。
class Solution {
public:
    struct Status {
        int val;
        ListNode *ptr;
        bool operator < (const Status &rhs) const {
            return val > rhs.val;
        }
    };

    priority_queue <Status> q;

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        for (auto node: lists) {
            if (node) q.push({node->val, node});
        }
        ListNode head, *tail = &head;
        while (!q.empty()) {
            auto f = q.top(); q.pop();
            tail->next = f.ptr; 
            tail = tail->next;
            if (f.ptr->next) q.push({f.ptr->next->val, f.ptr->next});
        }
        return head.next;
    }
};

时间复杂度 :考虑优先队列中的元素不超过 k 个,那么插入和删除的时间代价为 O(logk),这里最多有 kn 个点,对于每个点都被插入删除各一次,故总的时间代价即渐进时间复杂度为 O(kn×logk)。
空间复杂度:这里用了优先队列,优先队列中的元素不超过 k 个,故渐进空间复杂度为 O(k)。

我们定义了一个结构体Status,修改了他的比较器。正常情况优先队列如果true,表示当前元素比右侧元素小,将右侧元素放到堆顶,实现大根堆。
改变operator后,当前元素比右侧元素大堆时候true,将右侧元素放到堆顶,实现小根堆。

这道题是关于链表的题,题目要求合并k个升序链表,实际上我们就可以有这么一个思路:我们将每个链表的元素都丢入小根堆中,然后将小根堆的元素依次组成一个新的链表。由于题目中已经升序排列好每个链表,也就是说每个链表的头节点的val是链表中最小的。

首先我们先将lists中每个链表头节点push到小根堆q中,然后我们定义一个新链表头节点head,还有一个指针tail用来指向链表的尾部。接下来我们不断循环,f代表的是小根堆中的堆顶头节点,即val最小,我们将他连接到我们新建的链表尾部tail->next = f.ptr;,接着更新tail的位置tail = tail->next;使其在队尾。接着我们检查f节点的链表中是否还有其他节点,如果f.ptr->next存在,就将其连接的下一个节点推入到小根堆中,以便进行比较后插入到新建合并链表的合适位置。

最后返回head.next,这是因为head只是虚拟的头节点。

以及为什么我们不直接将节点的val一次性全部放入q中呢?因为当q的元素不断增加,插入的时间复杂度也在增加。堆的插入操作需要将元素插入到堆的最底层,并通过"上浮"操作将该元素移动到正确的位置。这个过程需要的时间复杂度是 O(log k),其中 k 是堆中元素的数量。

相关推荐
奋发向前wcx8 小时前
y1,y2总复习笔记5 2026.7.19
数据结构·笔记·算法
ChaoZiLL13 小时前
我的数据结构4-栈和队列
数据结构
miller-tsunami13 小时前
顺序表相关知识点
数据结构·顺序表
旖-旎13 小时前
LeetCode 279:完全平方数(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
良木林16 小时前
滑动窗口 - LeetCode hot 100
javascript·算法·leetcode·双指针·滑动窗口
华玥作者16 小时前
uniapp 万条数据不卡顿:我写了个虚拟列表组件 hy-list,原生支持瀑布流
数据结构·uni-app·list·vue3
2401_8414956416 小时前
【数据结构】B*树
数据结构·c++·b树·算法·删除·插入·三分分裂
晚笙coding16 小时前
LeetCode 108:将有序数组转换为二叉搜索树 —— 从数组到平衡二叉树的递归构造
数据结构·算法·leetcode
不如语冰16 小时前
AI大模型入门-模块导入import
数据结构·人工智能·pytorch·python
岑梓铭17 小时前
《考研408数据结构》第七章(7.1 查找:顺序查找、折半查找、分块查找)复习笔记
数据结构·笔记·考研·408·ds·查找