这是一道基本的归并排序问题,设定步长d初始为1,然后以指数增长归并向量元素
每次归并的思想就是将后一个链表的元素插入前一个链表,如果前一个链表为空,则前一个链表直接指向后一个链表
当d大于等于n时结束归并,返回第一个向量元素即为所求
#include <iostream>
#include <vector>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
/**
* merge listNode l2 into l1
*/
void mergeKLists(ListNode * &l1,ListNode * &l2) {
if(!l1) {// when l1 is null link l1 to l2 and make the merge over
l1 = l2;
return;
}
ListNode *start = l1;//record the first node of list node
ListNode * pre = NULL;// record the pre Node of l1
ListNode * ln2 = NULL;// record the next Node of l2
while(l1 && l2){
if(l2->val < l1->val){//when l2->val < l1->val insert into between (pre,l1)
if(pre) pre->next = l2;// when pre is not null pre link to l2
else start = l2; // when pre is null, it is the first node
pre = l2; //pre move to l2
ln2 = l2->next;
l2->next = l1;//l2 link to l1
l2 = ln2; //l2 move to next
}else {//when l2->val > l1->val pre move to l1 and l1 move to next
pre = l1;
l1 = l1->next;
}
}
if(l2) pre->next = l2; //when l2 is not null ,all elements in l2 must larger than l1,so link l1 to l2
l1 = start;//l1 return to first node
}
ListNode *mergeKLists(vector<ListNode *> &lists) {
int n = (int)lists.size();
if(!n) return NULL;
int d=1; // distance for merge like 1 2 4 8 16 ...
while(d<n){
for(int i=0;i+d<n;i+=2*d){
mergeKLists(lists[i],lists[i+d]);
}
d*=2;
}
return lists[0];
}
};
ListNode * buildListNode(int d){
ListNode *tmp = NULL,* it;
ListNode * l1 = new ListNode(d);
it = l1;
for(int i=d+d;i<d*13;i+=d){
tmp = new ListNode(i);
it->next = tmp;
it = it->next;
}
return l1;
}
void displayListNode(ListNode * l){
while(l){
cout<<l->val<<" ";
l = l->next;
}
cout<<endl;
}
int main(int argc, const char * argv[]) {
srand(unsigned(time(0)));
Solution sol;
int n = 7;
ListNode *l[n];
for(int i=0;i<n;i++){
l[i] = buildListNode(i+1);
// displayListNode(l[i]);
}
ListNode * l1 = buildListNode(3);
ListNode * l2 = buildListNode(5);
displayListNode(l1);
displayListNode(l2);
// sol.mergeKLists(l1, l2);
// displayListNode(l1);
cout<<"-----------------------------"<<endl;
vector<ListNode *> ls = {l2,l1};
// for(int i=0;i<n;i++){
// ls.push_back(l[i]);
// }
displayListNode(sol.mergeKLists(ls));
return 0;
}