有了合并两个有序链表做铺垫,合并k个链表就容易实现了,但是,一开始我的想法并不科学:不断合并2个链表,这样一来要合并k-1次,时间复杂度为O(nk),太低效了。既然是合并,为何不用二分合并呢?二分合并只需要O(nlogk)的复杂度。
对于二分合并,要对k个链表做合并,即划分成[0,k/2], [k/2+1,k]两部分,然后做递归。
ListNode* mergeKLists(vector<ListNode*>& lists) {
int k = lists.size();
if(k == 0)
return NULL;
ListNode*head = mergeKListsHelper(lists, 0, k-1); //
return head;
}
ListNode* mergeKListsHelper(vector<ListNode*>& lists, int left, int right) {
if (left == right) //递归的终止条件
return lists[left];
int mid = (left + right) / 2;
ListNode *l1 = mergeKListsHelper(lists, left, mid); //递归的对链表进行合并
ListNode *l2 = mergeKListsHelper(lists, mid + 1, right);
return mergeTwoLists(l1, l2);
}
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { //此处为两个链表合并的算法,也可以使用递归。
if (l1 == NULL)
return l2;
if (l2 == NULL)
return l1;
ListNode *p1 = l1;
ListNode *p2 = l2;
ListNode *newlist;
if (p1->val < p2->val)
{
newlist = p1;
p1 = p1->next;
}
else
{
newlist = p2;
p2 = p2->next;
}
ListNode *p = newlist;
while (p1 != NULL && p2 !=NULL)
{
if(p1->val < p2->val)
{
p->next = p1;
p1 = p1->next;
p = p->next;
}
else
{
p->next = p2;
p2 = p2->next;
p = p->next;
}
}
if(p1 !=NULL)
{
p->next = p1;
}
if(p2 !=NULL)
{
p->next = p2;
}
return newlist;
}