问题提出
#23
合并K个排序链表
合并 k 个排序链表,返回合并后的排序链表。
示例:
1
2
3
4
5
6
7
8 > 输入:
> [
> 1->4->5,
> 1->3->4,
> 2->6
> ]
> 输出: 1->1->2->3->4->4->5->6
>
解题思路
k=2?
#21
合并两个有序链表
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。示例:
1
2
3 > 输入:1->2->4, 1->3->4
> 输出:1->1->2->3->4->4
>
合并两个有序链表比较简单,每次取出链表头,将较小的加入到新链表中,并将这个较小的项从原链表中删除。重复这个过程,直到其中一个链表为空。这时再将那个非空的链表加到新链表的末尾即可。
1 | ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { |
k为任意值
借鉴上述k=2
的思路,算法步骤如下:
- 初始化:取出每个链表的第一个元素,将其排序,排序结果记录在
table:vector<int>
中。table
中记录的并不是链表中的元素,而是链表的序号,因此table
中的值为1~k
的一个排列 - 设
x
为table
中第一个元素对应的那个链表,如果x
为空,算法结束;如果x
非空,取出x
中的第一个元素,将其加到新链表中,并将其从x
中删除 - 更新
table
:同样设x
为table
中第一个元素对应的那个链表- 将
table
中的第一个元素删除 - 步骤2中刚刚删除了
x
的第一个元素,如果此时x
为空,将x
的序号加到table
的末尾;如果x
非空,根据x
中第一个元素的大小将x
的序号插入到table
中合适的位置
- 将
- 返回步骤2
细节优化
考虑k=0
或者传入的有些链表为空的情况,需要在执行上述算法之前进行预处理:删除空链表,删除后如果k=0
则直接返回NULL
这里记录一下删除 vector
中特定元素的方法:
1 | for (auto it = vec.begin(); it != vec.end();) { |
代码
1 | ListNode* mergeKLists(vector<ListNode*>& lists) { |