21. 合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = [] 输出:[]
示例 3:
输入:l1 = [], l2 = [0] 输出:[0]
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
//判空
if(list1==NULL)
{
return list2;
}
if(list2==NULL)
{
return list1;
}
//创建新的节点
struct ListNode* NewHead ,*NewTail;
NewHead=NewTail = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode*l1=list1;
struct ListNode*l2=list2;
while(l1&&l2)
{
if(l1->val>l2->val)
{
NewTail->next = l2;
NewTail=NewTail->next;
l2=l2->next;
}
else
{
NewTail->next = l1;
NewTail=NewTail->next;
l1=l1->next;
}
}
//出来就两种情况,要l1先走完,或l2先走完
if(l1)
{
NewTail->next=l1;
}
if(l2)
{
NewTail->next=l2;
}
//申请的节点要释放掉
struct ListNode * ret = NewHead->next;
free(NewHead);
NewHead =NULL;
return ret;
}
23. 合并 K 个升序链表
困难
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 解释:链表数组如下: [ 1->4->5, 1->3->4, 2->6 ] 将它们合并到一个有序链表中得到。 1->1->2->3->4->4->5->6
示例 2:
输入:lists = [] 输出:[]
示例 3:
输入:lists = [[]] 输出:[]
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode*mergeTwoList(struct ListNode*l1,struct ListNode*l2)
{
if(l1==NULL)
return l2;
if(l2==NULL)
return l1;
if(l1->val<l2->val)
{
l1->next=mergeTwoList(l1->next,l2);
return l1;
}
else
{
l2->next = mergeTwoList(l1,l2->next);
return l2;
}
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
//判空
if(lists==NULL||listsSize==0)
return NULL;
//分治
int interval =1;
while(interval<listsSize)
{
for(int i =0;i<listsSize-interval;i+=2*interval)
{
lists[i] = mergeTwoList(lists[i],lists[i+interval]);
}
interval*=2;
}
return lists[0];
}
假设我们有三个升序链表,每个链表中的元素分别为:
链表1:1 -> 4 -> 5
链表2:1 -> 3 -> 4
链表3:2 -> 6
我们的目标是将这三个链表合并成一个升序链表。
初始时,我们设置interval为1,然后进入while循环。在第一次迭代中,我们将会合并两个链表,步长为2。
第一次迭代:
• 合并lists[0]和lists[1],即链表1和链表2,得到结果:1 -> 1 -> 3 -> 4 -> 4 -> 5。
• 合并lists[2]和空链表,因为lists[2]为空,所以结果仍为链表3:2 -> 6。
此时,interval乘以2,变为2。
第二次迭代:
• 合并lists[0]和lists[2],即上一次合并后的结果和链表3,得到最终结果:1 -> 1 -> 2 -> 3 -> 4 -> 4 -> 5 -> 6。
由于此时interval已经大于等于listsSize,所以while循环结束,算法执行完成。
这就是使用分治法合并K个升序链表的具体执行过程,通过每次迭代合并两个子问题,并将子问题的规模逐步增大,最终得到合并后的结果。