【数据结构-堆】【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 是堆中元素的数量。

相关推荐
Xin7708 小时前
LeetCode 23.合并 K 个升序链表(分治递归)
leetcode
Nil20811 小时前
leetcode 105从前序和中序遍历序列构造二叉树
算法·leetcode·职场和发展
一直C11 小时前
【数据结构】哈希表+算法复杂度与经典排序查找(C语言)
java·linux·开发语言·数据结构·算法·ubuntu·散列表
淡海水11 小时前
04-02-哈希-Dictionary-TKey-TValue-上-核心数据结构
数据结构·算法·c#·哈希算法·编译·字典·dictionary
Nil20812 小时前
leetcode 114二叉树展开为链表
leetcode·链表·深度优先
cz071012 小时前
hot100_搜索二维矩阵 II
算法·leetcode
疯狂打码的少年13 小时前
【数据结构】板块总结 + 下期预告(数据库技术)
数据结构·笔记·算法
郝学胜-神的一滴13 小时前
Effective Python 条款 1:确认你正在使用的 Python 版本
开发语言·数据结构·python·程序人生·算法
圣保罗的大教堂14 小时前
leetcode 3718. 缺失的最小倍数 简单
leetcode
dtq042414 小时前
数据结构 - 线性表 - 单链表
数据结构