hello world 我是刘天昊,今天给大家带来的是链表的合并,用到了之前说的合并排序的思想
先看题目Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
我们先看看合并两个链表的操作
struct ListNode *merge(struct ListNode *l1,struct ListNode *l2)
{
if(l1==NULL)
{
return l2;
}
if(l2==NULL)
{
return l1;
}
struct ListNode *res,*p;
if(l1->val<l2->val)
{
res=l1;
l1=l1->next;
}
else
{
res=l2;
l2=l2->next;
}
p=res;
while(l1!=NULL&&l2!=NULL)
{
if(l1->val<l2->val)
{
p->next=l1;
l1=l1->next;
}
else
{
p->next=l2;
l2=l2->next;
}
p=p->next;
}
if(l1!=NULL)
{
p->next=l1;
}
if(l2!=NULL)
{
p->next=l2;
}
return res;
}
大概什么意思呢
假设L1: 1->3->7->9->10->11->12->13
L2: 2->4->6->8
先比较L1和L2的第一个数
L1小把res指向L1的1,然后把L1的头指针向后移
然后p=res主要方便移动p指针
然后按照前面所说的步骤
完成后如下图对着代码比划比划
图片
接着思考如何完成K个链表的合并
方案一:一个一个合--1和2合 合完的结果和3合代码不上了比较慢300多ms吧
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *merge(struct ListNode *l1,struct ListNode *l2)
{
if(l1==NULL)
{
return l2;
}
if(l2==NULL)
{
return l1;
}
struct ListNode *res,*p;
if(l1->val<l2->val)
{
res=l1;
l1=l1->next;
}
else
{
res=l2;
l2=l2->next;
}
p=res;
while(l1!=NULL&&l2!=NULL)
{
if(l1->val<l2->val)
{
p->next=l1;
l1=l1->next;
}
else
{
p->next=l2;
l2=l2->next;
}
p=p->next;
}
if(l1!=NULL)
{
p->next=l1;
}
if(l2!=NULL)
{
p->next=l2;
}
return res;
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
{
if(listsSize==0)
{
return NULL;
}
if(listsSize==1)
{
return *lists;
}
struct ListNode *temp=merge(*lists,*(lists+1));
if(listsSize==2)
{
return temp;
}
for(int i=2;i<listsSize;i++)
{
temp=merge(temp,*(lists+i));
}
return temp;
}
最后还是po了
现在重点是方案2--分治法,整个思路和归并排序一致感兴趣的看我讨论归并排序的那篇博客
简单说下先把k个链表分为两组,在依次分,分到只有0,1,2个时候合并,依次往上合并po上代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *merge(struct ListNode *l1,struct ListNode *l2)
{
if(l1==NULL)
{
return l2;
}
if(l2==NULL)
{
return l1;
}
struct ListNode *res,*p;
if(l1->val<l2->val)
{
res=l1;
l1=l1->next;
}
else
{
res=l2;
l2=l2->next;
}
p=res;
while(l1!=NULL&&l2!=NULL)
{
if(l1->val<l2->val)
{
p->next=l1;
l1=l1->next;
}
else
{
p->next=l2;
l2=l2->next;
}
p=p->next;
}
if(l1!=NULL)
{
p->next=l1;
}
if(l2!=NULL)
{
p->next=l2;
}
return res;
}
struct ListNode *mergeK(struct ListNode **lists,int left,int right)
{
if(left>right)
{
return NULL;
}
if(right==left)
{
return *(lists+left);
}
int mid=(left+right)/2;
struct LinkNode *l1=mergeK(lists,left,mid);
struct LinkNode *l2=mergeK(lists,mid+1,right);
return merge(l1,l2);
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)
{
struct ListNode *temp=mergeK(lists,0,listsSize-1);
return temp;
}
这次就到这,话说最近好像进入瓶颈了