📌  相关文章
📜  合并k个排序链表|设置 2(使用最小堆)(1)

📅  最后修改于: 2023-12-03 14:50:39.931000             🧑  作者: Mango

合并k个排序链表|设置 2(使用最小堆)

在合并k个排序链表的问题中,我们可以使用最小堆来更高效地解决问题。

最小堆

最小堆是一种树形数据结构,它满足以下两个条件:

  1. 堆中每一个节点的值都必须不大于其子树中的任何一个节点的值。
  2. 堆是一棵完全二叉树。

在最小堆中,根节点的值永远是最小的。因此,在合并多个有序链表的时候,我们可以将每条链表的头节点都放入最小堆中。每次从最小堆中取出的节点就是当前各条链表中最小的节点,将其放入合并后的链表中。

在将节点放入最小堆中时,我们可以使用链表节点自带的val值作为键值,将节点本身作为值。在C++中,可以使用STL中的priority_queue来实现最小堆。

实现

以下是使用最小堆解决合并k个有序链表问题的C++代码片段:

struct compare {
    bool operator()(const ListNode* l, const ListNode* r) {
        return l->val > r->val;
    }
};

class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        priority_queue<ListNode*, vector<ListNode*>, compare> q;
        for (auto l : lists) {
            if (l) {
                q.push(l);
            }
        }
        ListNode dummy(0);
        ListNode* tail = &dummy;
        while (!q.empty()) {
            ListNode* node = q.top();
            q.pop();
            tail->next = node;
            tail = tail->next;
            if (node->next) {
                q.push(node->next);
            }
        }
        return dummy.next;
    }
};
时间复杂度

使用最小堆来合并k个有序链表的时间复杂度为O(Nlogk),其中N为所有节点的总数,k为链表的数量。因为每个节点都会被加入堆中一次,而堆的大小最大为k,因此不会超过k*N次操作。每次操作的时间复杂度为logk。