Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
题意:将k个排序链表合并为一个新的排序链表。
要注意的地方:
1)memset的用法,这里花了我很长时间,关键在于char buffer1[20]和char *buffer2=new int[k],k=20是不一样的,因为buffer1是数组,sizeof(buffer1)=20,而buffer2是一个指针,sizeof(buffer2)=4。
void *memset(void *s, char ch, size_t n);的解释是将s中前n个字节 (typedef unsigned int size_t)用 ch 替换并返回 s 。故这里第三个参数可以用sizeof(buffer1),但不能用sizeof(buffer2),而是要sizeof(char)*k。
2)每次取得每个链表的头结点,比较最小值,然后将最小值所在的链表向后移动一个结点。(其实这里也可以不比较结点的值,而是通过让min=-1,-1指的是lists的下标,如果遍历一边lists后,min仍为-1,表明已经合并完成。不然的话选取lists[min]->val即为最小值。
3)直到所有的链表都遍历一遍后,这个合并完成。
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
unsigned int k=lists.size();
if(k==0)
return NULL;
if(k==1)
return lists[0];
ListNode *head=NULL,*p=NULL;
int *a=new int[k];
memset(a,0,k);
int pos;
bool *NotNULL=new bool[k]; //判断是否k个链表都为空
memset(NotNULL,true,k);
int flag=0;
while(true)
{
flag=0;
for(unsigned int i=0;i<k;i++)
{
if(lists[i])
a[i]=lists[i]->val;
else
{
NotNULL[i]=false;
flag++;
}
}
if(flag==k)
break;
int min=minimum(a,NotNULL,k,pos);
lists[pos]=lists[pos]->next;
if(head==NULL)
{
head=new ListNode(min);
p=head;
}
else
{
ListNode *node=new ListNode(min);
p->next=node;
p=p->next;
}
}
return head;
}
int minimum(int a[],bool notNULL[],unsigned int k,int &pos)
{
int min=~(1<<31);
for(unsigned int i=0;i<k;i++)
{
if(notNULL[i])
{
if(a[i]<min)
{
min=a[i];
pos=i;
}
}
}
return min;
}
};