力扣——23合并升序链表
目录
1:题目描述:
2.算法思想:
3.代码展示:
1:题目描述:
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 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 = [[]] 输出:[]
2.算法思想:
-
义比较器:
- 由于
priority_queue
默认是大根堆(堆顶元素最大),而我们希望每次取出最小的元素 - 自定义比较器
Compare
,当l1->val > l2->val
时返回true
,这样构造出小根堆
- 由于
-
初始化优先级队列:
- 创建一个存储
ListNode*
的小根堆pq
- 创建一个存储
-
将所有链表元素入队:
- 遍历输入的
lists
数组 - 对于每个链表,从头节点开始,将所有节点依次加入优先级队列
- 注意:这里直接将原链表的节点拆散加入队列,会破坏原链表结构
- 遍历输入的
-
构建结果链表:
- 创建一个虚拟头节点
dummy
简化操作 - 使用指针
p
跟踪当前链表的末尾 - 循环从优先级队列中取出最小元素(堆顶):
- 将取出的节点连接到
p->next
p
移动到新连接的节点- 从队列中移除该节点
- 将取出的节点连接到
- 创建一个虚拟头节点
-
返回结果:
- 返回
dummy.next
,即合并后的链表头节点
- 返回
3.代码展示:
//因为priority_queue默认是大根堆,堆顶是最大的元素,所以我们需要自定比较器,让它从小到大class Compare {public:bool operator()(ListNode* l1, ListNode* l2) {return l1->val > l2->val;}
};ListNode* mergeKLists(vector<ListNode*>& lists) {//使用优先级队列,priority_queue<ListNode*, vector<ListNode*>, Compare>pq;//把lists的每个元素都入队for (int i = 0; i < lists.size(); i++) {while (lists[i]){pq.push(lists[i]);lists[i] = lists[i]->next;}}//重新定义一个链表ListNode dummy(-1);ListNode* p = &dummy;//始终指向最后一个元素,开始链表为空,故指向头节点//接下来开始循环pq,while (!pq.empty()){p->next = pq.top();pq.pop();p = p -> next;}return dummy.next;}
23. 合并 K 个升序链表 - 力扣(LeetCode)https://leetcode.cn/problems/merge-k-sorted-lists/