题目
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
思路
- k个链表求和,可以让链表两两求和。
代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
if ( lists.size() == 0 ) return nullptr;
if ( lists.size() == 1 ) return lists[0];
int step = 1; // 合并的两个链表的距离
int size = lists.size();
while ( step < size ) {
for ( int i = 0; i <= size / ( 2 * step ); ++i ) { // 每相邻的两个区间为step的链表合并。可以这么理解,size / step可以表示为长度为step的区间一共有多少个。除以2表示共有几个两两合并。
int first = i * 2 * step;
if ( first + step < size ) // 如果是奇数个区间,最后一个不参与合并。
lists[first] = merge2Lists( lists[first], lists[first+step] );
}
step *= 2;
}
return lists[0];
}
ListNode* merge2Lists( ListNode* l1, ListNode* l2 ) {
ListNode* dummyHead = new ListNode( 0 );
ListNode* p = dummyHead;
while ( l1 && l2 ) {
if ( l1->val < l2->val ) {
p->next = l1;
l1 = l1->next;
}
else {
p->next = l2;
l2 = l2->next;
}
p = p->next;
}
p->next = l1 ? l1 : l2;
p = dummyHead->next;
dummyHead->next = nullptr;
delete dummyHead;
return p;
}
};