😀前言
在算法面试中,链表问题是经常遇到的考点之一,其中合并两个排序链表是一个非常经典的问题。本文将详细介绍如何通过递归和迭代两种方式实现两个有序链表的合并。
🏠个人主页:尘觉主页
文章目录
- 😀合并两个排序的链表
- 😉题目描述
- 示例1
- 示例2
- 示例3
- 🤔解题思路
- 🥰递归解法
- 递归解法的分析
- 🥰迭代解法
- 迭代解法的分析
- 😄总结
😀合并两个排序的链表
NowCoder
😉题目描述
输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。
数据范围: 0≤n≤1000,−1000≤节点值≤1000
要求:空间复杂度 O(1),时间复杂度 O(n)
如输入{1,3,5},{2,4,6}时,合并后的链表为{1,2,3,4,5,6},所以对应的输出为{1,2,3,4,5,6},转换过程如下图所示:
或输入{-1,2,4},{1,3,4}时,合并后的链表为{-1,1,2,3,4,4},所以对应的输出为{-1,1,2,3,4,4},转换过程如下图所示:
示例1
- 输入:
{1,3,5}
和{2,4,6}
- 输出:
{1,2,3,4,5,6}
示例2
- 输入:
{}
和{}
- 输出:
{}
示例3
- 输入:
{-1,2,4}
和{1,3,4}
- 输出:
{-1,1,2,3,4,4}
🤔解题思路
要实现两个排序链表的合并,可以使用递归和迭代两种方法。下面分别详细讲解这两种方法的实现思路和代码。
🥰递归解法
递归解法的核心思想是比较两个链表的头节点值,并通过递归调用合并剩余部分的链表。具体而言:
- 如果
list1
的头节点值小于等于list2
的头节点值,则list1
的头节点应成为新链表的头节点,并递归合并list1
的剩余部分和list2
。 - 反之,则
list2
的头节点成为新链表的头节点,并递归合并list1
和list2
的剩余部分。
递归解法的代码实现如下:
public ListNode Merge(ListNode list1, ListNode list2) {if (list1 == null)return list2;if (list2 == null)return list1;if (list1.val <= list2.val) {list1.next = Merge(list1.next, list2);return list1;} else {list2.next = Merge(list1, list2.next);return list2;}
}
递归解法的分析
- 时间复杂度:
O(n)
。每次递归都会遍历一个节点,最终遍历完所有节点,因此时间复杂度为O(n)
。 - 空间复杂度:
O(n)
。由于递归调用占用了系统栈空间,递归深度为n
,空间复杂度为O(n)
,不满足题目对O(1)
空间复杂度的要求。
虽然递归解法简单直观,但在处理深度较大的链表时,可能会出现栈溢出的风险,因此在实际应用中通常更倾向于使用迭代解法。
🥰迭代解法
迭代解法通过维护一个指针逐步遍历两个链表,并根据节点值的大小将节点连接到新链表的末尾。具体实现步骤如下:
- 创建一个虚拟头节点
head
,用于存储合并后的链表。 - 使用
cur
指针遍历list1
和list2
,将较小值的节点链接到cur
后面,然后移动cur
和相应链表的指针。 - 如果一个链表遍历完了,直接将另一个链表剩余部分链接到
cur
后面。 - 最后返回
head.next
,即合并后的链表的头节点。
迭代解法的代码实现如下:
public ListNode Merge(ListNode list1, ListNode list2) {ListNode head = new ListNode(-1);ListNode cur = head;while (list1 != null && list2 != null) {if (list1.val <= list2.val) {cur.next = list1;list1 = list1.next;} else {cur.next = list2;list2 = list2.next;}cur = cur.next;}if (list1 != null)cur.next = list1;if (list2 != null)cur.next = list2;return head.next;
}
迭代解法的分析
- 时间复杂度:
O(n)
。同样,迭代过程中会遍历所有节点,因此时间复杂度为O(n)
。 - 空间复杂度:
O(1)
。只使用了常量级别的额外空间,满足题目对O(1)
空间复杂度的要求。
迭代解法不仅在时间和空间复杂度上更加符合题目的要求,还避免了递归深度过大的问题,因此在实际开发中更为常用。
😄总结
合并两个排序链表问题通过递归和迭代两种方法均可以有效解决。递归解法简单直观,但在空间复杂度上有所不足;迭代解法在时间和空间效率上更为优越,是实际应用中的首选方案。
希望通过本文的详细讲解,大家能够掌握这两种合并排序链表的技巧,并在算法面试或实际开发中灵活运用。
😁热门专栏推荐
想学习vue的可以看看这个
java基础合集
数据库合集
redis合集
nginx合集
linux合集
手写机制
微服务组件
spring_尘觉
springMVC
mybits
等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持
🤔欢迎大家加入我的社区 尘觉社区
文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞