一.题目:
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = [] 输出:[]
示例 3:
输入:l1 = [], l2 = [0] 输出:[0]
二.详细代码:
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
if(list1==NULL)
return list2;
if(list2==NULL)
return list1;
if(list1->val < list2->val) //递归情况:比较两个链表的当前节点,选择较小的节点作为新链表的下一个节点
{
list1->next=mergeTwoLists(list1->next,list2);
return list1;
}
else
{
list2->next=mergeTwoLists(list1,list2->next);
return list2;
}
}
三.代码解释:
4.1递归思想(自身调用)
将一个复杂的问题分解为若干个子问题(与原问题相同或相似但规模较小),直到子问题可以简单地直接求解,原问题的解即子问题的解的合并。
使用递归思想的关键点:
(1)必须有明确的基准情形(或称边界条件),即不需要递归就能解出的情形。这是递归的结束条件,防止无限递归。
(2)对于复杂问题,需要找出如何将其分解为子问题的方法,并明确子问题与原问题的关系
(3)在递归关系中,需要调用自身来解子问题。
(4)合并结果:将子问题的解合并起来,形成原问题的解。
举个栗子:
阶乘函数factorial(n)
可以定义为:
- 如果
n
是0,那么factorial(n)
的值是1(基准情形)。 - 否则,
factorial(n)
的值是n * factorial(n-1)
(递归关系)。
4.2本题讲解
两个递归单链表list1与list2,合并为一个有序单链表,首先,需要确定递归的基本情况,也就是当其中一个链表为空时,我们可以直接返回另一个链表。然后,确定递归的步骤,即比较两个链表的当前节点,将较小的节点连接到新链表中,并递归地处理剩余的部分。
(即比较list1
和list2
当前节点的值。如果list1
的当前节点值小于list2
的当前节点值,将list1
的当前节点作为新链表的下一个节点,并递归地调用mergeTwoLists
函数来合并list1
的下一个节点和list2
。然后返回list1
。如果list2
的当前节点值小于或等于list1
的当前节点值(注意这里使用了小于或等于,因为可能有重复值),执行类似的操作,但是是针对list2
的。将list2
的当前节点作为新链表的下一个节点,并递归地调用mergeTwoLists
函数来合并list1
和list2
的下一个节点。然后返回list2
。通过这种方式,不断地将较小的节点连接到新链表中,并递归地处理剩余部分,直到其中一个链表为空,此时直接返回另一个链表(基本情况))
四.运行结果:
-----ssss