合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
思路:
同时处理多个链表很复杂,但处理两个链表很简单,用递归即可解决。所以可以把问题转换为解决多个子问题:合并两个链表,用分治即可。
代码:
//处理两个链表 返回头指针
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
{
if (!l1) return l2;
else if (!l2) return l1;
else
{
struct ListNode* head = NULL;
if (l1 -> val < l2 -> val)//将较小者放入链表
{
head = l1;
head -> next = mergeTwoLists(l1 -> next, l2);
}
else
{
head = l2;
head -> next = mergeTwoLists(l1, l2 -> next);
}
return head;
}
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
{
if (listsSize == 0)
return NULL;
else if (listsSize == 1)
return lists[0];
else if (listsSize == 2)
{
return mergeTwoLists(lists[0], lists[1]);;
}
else//将原链表数组分为两部分,分别处理得到两个链表在合并
{
struct ListNode* l1 = mergeKLists(&lists[0], (listsSize + 1) / 2);
struct ListNode* l2 = mergeKLists(&lists[(listsSize + 1) / 2],
listsSize -(listsSize + 1) / 2);
return mergeTwoLists(l1, l2);
}
}
注意点:
- 将输入分为两部分时不要弄错两端各自的链表数(就是注意left,mid,right的取值),这个要特别小心,有时候会丢失数据。