题目
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
示例1:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
限制:0 <= 链表长度 <= 1000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof
写在前面
本篇文章思路部分内容引用自作者:huwt,个人认为其概括全面且易懂
解题思路
我们的目的是将两个有序链表合并成一个有序链表,因此,我们的每次操作都是获取L1指向的节点和L2指向的节点中,值较小的节点。迭代和递归都是如此。
-
使用迭代的时候
- 为了将第一个节点与其余节点统一处理,一般会定义一个头结点。
-
使用递归的时候
-
我们往往可以利用递归函数的返回值,将处理好的链表的第一个节点,作为返回值返回到上一级。
-
上一级函数则直接将得到的返回值,链接在当前节点的next 即可。
-
解题一: 迭代
- 定义头节点
- 若 L1指向的节点值 < L2指向的节点值,则将L1链接到头节点的 next位置,否则将L2链接到头节点的 next 位置
- 循环进行,直至L1或 L2为 null / nil
- 最后,将 L1或 L2中剩下的部分,链接到头节点后面
代码
–执行时间:8 ms --消耗内存:4.1 MB
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
cur:=new(ListNode)
ret:=cur//定义头节点
for l1!=nil && l2!=nil{
if l1.Val<=l2.Val && l1!=nil{
cur.Next=l1
l1=l1.Next
}else{
cur.Next=l2
l2=l2.Next
}
cur=cur.Next
}
//将 L1或 L2中剩下的部分,链接到头节点后面
if l1!=nil{
cur.Next=l1
}
if l2!=nil{
cur.Next=l2
}
return ret.Next
}
解题二:递归
编写递归的第一步,应当是明确当前函数应当完成的功能。
-
函数功能
- 返回 L1 指向的节点和 L2 指向的节点中值较小的节点
并将从下级函数获得的返回值,链接到当前节点尾部
- 返回 L1 指向的节点和 L2 指向的节点中值较小的节点
-
函数结束条件
- 当 L1 为空 或 L2 为空 ,函数结束,返回 L1 或 L2 中剩下的部分
代码
–执行时间:8 ms --消耗内存:4.3 MB
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
if l1==nil{
return l2
}
if l2==nil{
return l1
}
if l1.Val<=l2.Val{
l1.Next=mergeTwoLists(l1.Next,l2)
return l1
}
l2.Next=mergeTwoLists(l2.Next,l1)
return l2
}