问题
思路
归并的思路,谁小谁走。
多文件排序的时候,也是这个思路,此时的指针换成文件指针。
时间复杂度是
O(k2N)
.
网上有一种办法是每次合并两个,但是这样是依次的,就是1,2合并,然后结果和3合并,再和4合并。这样每次都要重复比较之前的元素。不好。
代码
/**
* 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) {
ListNode* head = NULL;
ListNode* tail = head;
int sz = lists.size();
if(!sz) return NULL;
while(valid(lists)){
int min = INT_MAX;
int u = -1;
for( int i = 0; i < sz; ++i ){
if( lists[i] ){
if( lists[i]->val < min ){
min = lists[i]->val;
u = i;
}
}
}
ListNode* s = new ListNode(min);
lists[u] = lists[u]->next;
if( !tail ){
head = tail = s;
}else{
tail->next = s;
tail = s;
}
}
return head;
}
private:
bool valid( vector<ListNode*>& lists ){
int sz = lists.size();
if( !sz ) return false;
for(int i = 0; i < sz; ++i){
if( lists[i] ) return true;
}
return false;
}
};
思路1
上面的思路比较像是直接使用Merge的思路。
下面的思路是利用mergeSort的思路,两两进行合并的思路。
代码1
/**
* 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) {
int n = lists.size();
if( !n ) return NULL;
while(n > 1){
int step = (n+1)/2;
for(int i = 0; i < n/2; ++i){
lists[i] = merge2Lists( lists[i], lists[i+step] );
}
n = step; // update n
}
return lists[0];
}
private:
ListNode* merge2Lists(ListNode* l1, ListNode* l2){
if(!l1 && !l2) return NULL;
if( l1 && !l2 ) return l1;
if( !l1 && l2 ) return l2;
ListNode* head = NULL;
ListNode* tail = head;
while(l1 && l2){
if( l1->val < l2->val ){
ListNode* s = new ListNode(l1->val);
if( !tail ){
head = tail = s;
}else{
tail->next = s;
tail = s;
}
l1 = l1->next;
}else{
ListNode* s = new ListNode(l2->val);
if(!tail) head = tail = s;
else{
tail->next = s;
tail = s;
}
l2 = l2->next;
}
}
while(l1){
ListNode* s = new ListNode(l1->val);
tail->next = s;
tail = s;
l1 = l1->next;
}
while(l2){
ListNode* s = new ListNode(l2->val);
tail->next = s;
tail = s;
l2 = l2->next;
}
return head;
}
};