23. 合并 K 个升序链表
代码
ts
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function mergeKLists(lists: Array<ListNode | null>): ListNode | null {
let res = null;
for(let i = 0; i < lists.length; i++){
res = merge2Lists(res, lists[i]);
}
return res;
};
function merge2Lists(list1: ListNode | null, list2: ListNode | null){
let dummy = new ListNode();
let head = dummy, head1 = list1, head2 = list2;
while(head1 && head2){
if(head1.val < head2.val){
head.next = head1;
head1 = head1.next;
}
else{
head.next = head2;
head2 = head2.next;
}
head = head.next;
}
head.next = head1 ? head1: head2;
return dummy.next;
}思路
使用顺序合并的方法,逐个合并链表:
主要步骤
- 初始化结果链表
res = null - 遍历
lists数组,依次将每个链表与结果链表合并 - 使用辅助函数
merge2Lists合并两个有序链表
辅助函数 merge2Lists
合并两个有序链表的经典方法:
- 创建哑节点
dummy作为结果链表的起始点 - 使用指针
head指向当前构建位置 - 比较两个链表的当前节点,选择较小的连接到结果链表
- 当其中一个链表遍历完后,直接连接另一个链表的剩余部分
- 返回
dummy.next
复杂度分析
假设有
第一次合并:
第二次合并:
第
次合并: 总时间复杂度:
时间复杂度
,其中 是链表数量, 是平均链表长度 空间复杂度