题目
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 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 = [[]]
输出:[]
        提示:
k == lists.length0 <= k <= 10^40 <= lists[i].length <= 500-10^4 <= lists[i][j] <= 10^4lists[i]按 升序 排列lists[i].length的总和不超过10^4
代码展示
            
            
              cpp
              
              
            
          
          #include <queue>
using namespace std;
struct Compare {
    bool operator()(ListNode* a, ListNode* b) {
        return a->val > b->val; // 最小堆
    }
};
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        priority_queue<ListNode*, vector<ListNode*>, Compare> pq;
        
        
        for (auto& list : lists) {
            if (list) {
                pq.push(list);
            }
        }
        
        ListNode* dummy = new ListNode(0);
        ListNode* current = dummy;
        
        while (!pq.empty()) {
            ListNode* top = pq.top();
            pq.pop();
            
            current->next = top;
            current = current->next;
            
            if (top->next) {
                pq.push(top->next);
            }
        }
        
        return dummy->next;
    }
};
        写者心得
练习中曾经做过合并两个链表的题,然后写者准备加一个循环,就是把他给的这个数组里面的链表提取出来之后再合并起来,但是运行出了bug,于是我就去找到了这样一个和我当初思路截然不同的做法,这个利用的是栈,代码比我当初利用for循环来进行链表合并要少很多
逐行解析
- 
自定义比较器:
struct Compare { bool operator()(ListNode* a, ListNode* b) { return a->val > b->val; // 最小堆 } };- 这是一个自定义的比较器,用于优先队列中的排序。
 operator()定义了比较规则,使得优先队列成为一个最小堆,即队列顶部的节点值是最小的。
 - 
创建优先队列:
priority_queue<ListNode*, vector<ListNode*>, Compare> pq;- 使用 
priority_queue创建一个最小堆,存储类型为ListNode*。 vector<ListNode*>是优先队列的底层容器。Compare是自定义的比较器,确保优先队列按节点值从小到大排序。
 - 使用 
 - 
初始化优先队列:
for (auto& list : lists) { if (list) { // 检查链表是否为空 pq.push(list); } }- 遍历输入的链表列表 
lists。 - 对于每个链表,检查其是否为空(
if (list)),如果不为空,则将其头节点加入优先队列。 
 - 遍历输入的链表列表 
 - 
创建虚拟头节点:
ListNode* dummy = new ListNode(0); ListNode* current = dummy;- 创建一个虚拟头节点 
dummy,值为 0。 current指向dummy,用于构建新的链表。
 - 创建一个虚拟头节点 
 - 
合并链表:
while (!pq.empty()) { ListNode* top = pq.top(); pq.pop(); current->next = top; current = current->next; if (top->next) { pq.push(top->next); } }- 当优先队列不为空时,进入循环。
 - 从优先队列中取出当前最小的节点 
top。 - 将 
top添加到新链表中,即current->next = top,并移动current到top。 - 如果 
top有下一个节点(if (top->next)),则将top->next加入优先队列。 
 - 
返回新链表的头节点:
return dummy->next;- 返回新链表的头节点,即 
dummy的下一个节点。 
 - 返回新链表的头节点,即 
 
条件的使用
if (list):检查链表是否为空。只有非空链表的头节点才会被加入优先队列。if (top->next):检查当前节点是否有下一个节点。如果有,则将下一个节点加入优先队列,以继续参与后续的合并操作。
1. 自定义比较器
什么是比较器?
比较器是一个函数对象,用于定义两个对象之间的比较规则。在 C++ 标准库中,许多容器(如 std::sort、std::priority_queue)都允许用户自定义比较器。
自定义比较器的例子
struct Compare {
    bool operator()(ListNode* a, ListNode* b) {
        return a->val > b->val; // 最小堆
    }
};
        struct Compare:定义一个结构体Compare,用于存储比较逻辑。bool operator()(ListNode* a, ListNode* b):重载()操作符,使其像一个函数一样调用。- 参数 
a和b是两个ListNode*类型的指针。 - 返回值 
bool表示a是否大于b。 return a->val > b->val;:如果a的值大于b的值,返回true,否则返回false。这使得优先队列成为一个最小堆。
- 参数 
 
2. 创建优先队列
什么是优先队列?
优先队列是一种特殊的队列,取出元素的顺序并不是按照进入的顺序,而是根据元素的优先级。在 C++ 中,std::priority_queue 是一个容器适配器,默认情况下是一个最大堆(即队列顶部的元素是最大的)。
创建最小堆的优先队列
priority_queue<ListNode*, vector<ListNode*>, Compare> pq;
        priority_queue<ListNode*, vector<ListNode*>, Compare>:- 第一个模板参数 
ListNode*:优先队列中存储的元素类型。 - 第二个模板参数 
vector<ListNode*>:底层容器,用于存储元素。默认情况下是vector。 - 第三个模板参数 
Compare:自定义的比较器,用于定义元素的优先级 
- 第一个模板参数