文章目录
- 1. 题目
- 2. 思路及代码实现(Python)
- 2.1 递归
- 2.2 迭代
1. 题目
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入: l 1 = [ 1 , 2 , 4 ] , l 2 = [ 1 , 3 , 4 ] l1 = [1,2,4], l2 = [1,3,4] l1=[1,2,4],l2=[1,3,4]
输出: [ 1 , 1 , 2 , 3 , 4 , 4 ] [1,1,2,3,4,4] [1,1,2,3,4,4]
示例 2:
输入: l 1 = [ ] , l 2 = [ ] l1 = [], l2 = [] l1=[],l2=[]
输出: [ ] [] []
示例 3:
输入: l 1 = [ ] , l 2 = [ 0 ] l1 = [], l2 = [0] l1=[],l2=[0]
输出: [ 0 ] [0] [0]
提示:
- 两个链表的节点数目范围是 [ 0 , 50 ] [0, 50] [0,50]
- 100 ≤ N o d e . v a l ≤ 100 100 \leq Node.val \leq 100 100≤Node.val≤100
- l 1 l1 l1 和 l 2 l2 l2 均按 非递减顺序 排列
2. 思路及代码实现(Python)
2.1 递归
可以通过递归的方式,不断地取出值较小的节点,并将该较小值节点指向后续链表和另一个链表得合并链表,不断地堆栈,直到到达边界条件,即最后一个节点指向 N o n e None None。用列表得形式直观地表示如下:
{ l i s t 1 [ 0 ] + m e r g e ( l i s t 1 [ 1 : ] , l i s t 2 ) l i s t 1 [ 0 ] < l i s t 2 [ 0 ] l i s t 2 [ 0 ] + m e r g e ( l i s t 1 , l i s t 2 [ 1 : ] ) o t h e r w i s e \left.\left\{\begin{array}{ll}list1[0]+merge(list1[1:],list2)&list1[0]<list2[0]\\list2[0]+merge(list1,list2[1:])&otherwise\end{array}\right.\right. {list1[0]+merge(list1[1:],list2)list2[0]+merge(list1,list2[1:])list1[0]<list2[0]otherwise
每次进行合并时,会取出两个链表地头节点,直到至少一个链表为空,在最差情况下,调用次数为两个链表长度之和 ( m + n ) (m+n) (m+n),即时间复杂度为 O ( m + n ) O(m+n) O(m+n),空间复杂度为为栈深,每调用一次栈深加一,因此空间复杂度也为 O ( m + n ) O(m+n) O(m+n)。
class Solution:def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:if l1 is None:return l2elif l2 is None:return l1elif l1.val < l2.val:l1.next = self.mergeTwoLists(l1.next, l2)return l1else:l2.next = self.mergeTwoLists(l1, l2.next)return l2
执行用时:43 ms
消耗内存:16.43 MB
2.2 迭代
前面的方式是用递归的方式,把除了取出的头节点之外的链表的合并,归纳为一个合并函数,不断去调用直至边界条件,实现链表的合并。如果不把合并的操作定义为函数反复自调,那其实就是迭代的思路。
这里我们可以设定一个哨兵节点 p r e h e a d prehead prehead ,该节点相当于另起一条链表,但最后返回结果的时候可以不包含该哨兵节点,该链表方便我们得到合并后的结果。通过维护一个 p r e v prev prev 指针,不断地调整该指针指向两个链表中值较小的头节点,不断迭代直至某个链表指向空节点,当 p r e v prev prev 指向某链表的头节点之后,该链表的头节点需更新为下一个节点。如果最后某链表为空,另外的链表还有剩余,则将剩余部分直接接到 p r e v prev prev 指针后面。
同样的,迭代次数在最差情况下为 ( m + n ) (m+n) (m+n) 次,时间复杂度为 O ( m + n ) O(m+n) O(m+n),但由于我们只维护一个指针,此时的空间复杂度为 O ( 1 ) O(1) O(1)。
class Solution:def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:prehead = ListNode(-1)prev = preheadwhile l1 and l2:if l1.val <= l2.val:prev.next = l1l1 = l1.nextelse:prev.next = l2l2 = l2.next prev = prev.nextprev.next = l1 if l1 is not None else l2return prehead.next
执行用时:34 ms
消耗内存:16.38 MB
题解来源:力扣官方题解