第一次尝试,思路:想象有n列个向量,每当要merge的时候,比较每一列的第一个大小,取下最小的那个节点返回并且将该节点从当前向量中剔除(search函数来完成)。当search函数返回NULL 的时候说明所有的node都被遍历了一边,所以标志着结束。
但是这个算法的复杂度比较高。假设有n个数字,每个数字在被取走之前都会被遍历一次,所以第x大的数字会被遍历x次的,所以复杂度O(n^2)
提醒超时TLE
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* search(struct ListNode** lists, int size);
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
struct ListNode *head,*forward,*next;
head=(struct ListNode*)malloc(sizeof(struct ListNode));
head->next=NULL;
forward=head;
while((next=search(lists,listsSize))!=NULL){
forward->next=next;
forward=next;
}
//next=NULL,no Node any more;
//no need to add the terminated NULL,cause the last node must\
//terminate with a NULL;
//forward->next=next;
forward=head;
head=forward->next;
free(forward);
return head;
}
struct ListNode* search(struct ListNode** lists, int size){
struct ListNode* temp=*lists;
size_t i=0;
int ptr;
for(;i!=size;i++){
if(temp==NULL) temp=*(lists+i);
else if((*(lists+i)!=NULL)&&((*(lists+i))->val)<(temp->val)) {
temp=*(lists+i);//temp save the pointer to smallest val
ptr=i;
}
}
if(temp==NULL) return NULL;
*(lists+ptr)=temp->next;
return temp;
}
第二次尝试:为降低复杂度,牺牲存储。将所有的链表的值复制到数组中,利用stdlib中的qsort快排达到nlogn的复杂度。
代码如下,依旧提醒超时。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
int cmp(const void *a, const void *b)
{
return *(int*)a - *(int*)b; //由小到大排序
//return *(int *)b - *(int *)a; 由大到小排序
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
struct ListNode*temp=*lists;
int array[1000];
int size=0; //indicate the size of array
for(int i=0;i<listsSize;i++)
{
struct ListNode*temp=*(lists+i);
while(temp!=NULL){
array[size++]=temp->val;
temp=temp->next;
}
}
if(size==0) return 0;
qsort(array,size,sizeof(int),cmp);
struct ListNode* head=(struct ListNode*)malloc(size*sizeof(struct ListNode));
temp=head;
int i=0;
while(i<size){
temp->val=array[i];
if(i!=size-1) {
temp->next=temp+1;
temp=temp->next;
}
}
temp->next=NULL;
return head;
}
第三次尝试:
=====================分割线==============
下次再写