题目介绍
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4]示例 2:
输入:l1 = [], l2 = [] 输出:[]示例 3:
输入:l1 = [], l2 = [0] 输出:[0]提示:
- 两个链表的节点数目范围是
[0, 50]
-100 <= Node.val <= 100
l1
和l2
均按 非递减顺序 排列
接下来是题目给我们单链表的信息
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
解法思路分析
首先让我们来分析题目,这是一个链表题,在处理链表时,递归和迭代都是可行的选择。但是,递归在处理链表问题时有一种天然的优势,因为链表本身就是递归定义的(每个节点都包含下一个节点的指针)。因此,递归方法往往能够更加直接地解决问题。所以我们就先定义一个递归函数
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
}
这是一个判断大小的题目,且两个需要合并的链表都是有序,所以我们可以先分析我们比较大小是会与到的各种情景,用if语句来解决不同情景下该如何合并链表
情景一
首先先解决特殊情况,当两个链表中有一个为空时,说明可以直接输出剩下的那个链表,由于两个链表都是有序链表,直接输出不会影响排序。
if(list1==NULL)
{
return list2;
}
else if(list2==NULL)
{
return list1;
}
情景二
接下来如果两个链表都不为空,我们就要比较list1和list2的头部节点的值。如果list1的值小于list2的值,则将list1的下一个节点与list2进行合并,并将合并后的结果作为list1的下一个节点。然后返回list1作为合并后的链表的头节点。
else if(list1->val<list2->val)
{
list1->next=mergeTwoLists(list1->next,list2);
return list1;
}
情景三
如果list1的值大于等于list2的值,则将list2的下一个节点与list1进行合并,并将合并后的结果作为list2的下一个节点。然后返回list2作为合并后的链表的头节点
else
{
list2->next=mergeTwoLists(list1,list2->next);
return list2;
}
由于这是个递归函数,这个过程会递归进行,直到其中一个链表为空。然后运行情景一的代码,结束递归,输出完整的合并后的单链表。
接下来是完整的代码
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
if(list1==NULL)
{
return list2;
}
else if(list2==NULL)
{
return list1;
}
else if(list1->val<list2->val)
{
list1->next=mergeTwoLists(list1->next,list2);
return list1;
}
else
{
list2->next=mergeTwoLists(list1,list2->next);
return list2;
}
}
知识点总结
这篇文章主要考我们是链表的理解,链表由节点组成,每个节点包含数据和指向下一个节点的指针,合并有序单链表首先要考虑递归解法,因为对于链表这类递归数据结构,递归操作通常比迭代操作更容易理解和实现。递归直接利用了链表的递归性质,使得代码更加直观。
然后要善于把握特殊情况,这个题目中链表因为是有序的,所以我们分析是首先就可以用if函数将链表为空后的特殊情况表示出来,然后直接输出剩下的链表,从而达到我们解题的目的。