Golang从合并链表聊递归
从合并链表聊递归
递归是工程师最常见的一种解决问题的方式,但是有时候不容易真正掌握。有人说是看起来很简单,自己写起来会费点劲。
最著名的例子就是斐波那契数列(Fibonacci sequence),通过寻找递推公式来计算出结果。
而最近刷到的一道合并链表的算法题,也可以使用递归来实现。下面看看题目描述吧:
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
来源:力扣(LeetCode)
先抛出本人观点,递归的关键是:找到边界条件和递归公式。
分析一下题目,可以发现用第一个链表l1的头部节点来去和l2的节点对比,如果大于l2的当前节点,那么偏移l1的next和l2继续对比大小。反之如果l1的头节点对比L2的当前节点更小,那么就需要对l2做类似处理。
这种不断对比和偏移的过程,可以总结出一种递归公式。
用伪代码写法就是:
if l1.val < l2.val:
l1.next = mergeTwoList(l1.next, l2)
return l1
else:
l2.next = mergeTwoList(l1, l2.next)
return l2
而边界条件就是在不断偏移的时候,走到某个链表的最后一个节点为止,伪代码就是:
if l1 === null:
return l2
if l2 === null:
return l1
用golang来实现,代码也很清晰:
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
} else {
l2.Next = mergeTwoLists(l1, l2.Next)
return l2
}
}
在LeetCode里面提交,运行反馈如下:
执行结果:
通过
显示详情
执行用时:
0 ms
, 在所有 Go 提交中击败了
100.00%
的用户
内存消耗:
2.6 MB
, 在所有 Go 提交中击败了
63.64%
的用户
可以看到递归是非常消耗内存的,它循环调用,犹如尔罗斯套娃,一层一层返回内层的调用结果。
如果要优化的话可以使用迭代方式来实现,代码需要做一些调整:
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
head := &ListNode{}
result := head
for l1 != nil && l2 != nil {
if l1.Val < l2.Val {
head.Next = l1
head = head.Next
l1 = l1.Next
} else {
head.Next = l2
head = head.Next
l2 = l2.Next
}
}
if l1 == nil {
head.Next = l2
}
if l2 == nil {
head.Next = l1
}
return result.Next
}
可以看出需要创建一个头部指针来做偏移,而最终result作为一个合成结果链表来存储结果。
最后提交执行,发现结果数据稍微好看了一丢丢:
执行用时:
4 ms
, 在所有 Go 提交中击败了
62.28%
的用户
内存消耗:
2.5 MB
, 在所有 Go 提交中击败了
100.00%
的用户
由于在数据量不大的情况下,其实性能差距也不大,所以使用递归也是没有毛病的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通