21. 合并两个有序链表
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4
一开始看到这个题目,很是迷惑,不熟悉链表的数据结构,不清楚 ListNode
参数对象是什么样子的,想要做这个题目,首先需要构建一个单链表。
单链表每个节点必然包含
- 自己的数据域
- 指向下一个节点的指针(尾节点指针为 NULL)
知道单链表的数据结构后,对于此题依旧毫无头绪,不知如何下手,只有先看题解,进行分析理解。
递归解法
与官方题解有点不同,对
l1.val == l2.val
节点值相等的情况,做了单独处理,减少了递归次数。public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null) { return l2; } else if (l2 == null) { return l1; } else if (l1.val < l2.val) { l1.next = mergeTwoLists(l1.next, l2); return l1; } else if (l1.val > l2.val) { l2.next = mergeTwoLists(l1, l2.next); return l2; } else { l2.next = mergeTwoLists(l1.next, l2.next); l1.next = l2; return l1; } }
-
首先判断
l1
和l2
是否为null
,如果为null
,直接返回另一方数据,这个比较好理解,一方为null
,直接使用另一方链表,不需要对链表的节点数据进行比较排序了。 -
如果
l1
和l2
节点都不为null
,那么比较两方节点中的数据值。分为三种情况
l1.val < l2.val
①l1
节点的位置确定,因为l1
节点的值小,按顺序要排在前面。 ②l2
节点的位置无法确定,需要与l1
节点的下一个节点值进行比较。 ③l1
节点的指针指向 ② 的结果。 ④ 返回l1
节点。l1.val > l2.val
①l2
节点的位置确定,因为l2
节点的值小,按顺序要排在前面。 ②l1
节点的位置无法确定,需要与l2
节点的下一个节点值进行比较。 ③l2
节点的指针指向 ② 的结果。 ④ 返回l2
节点。l1.val == l2.val
①l1
和l2
节点的位置都可以确定,且紧密相邻。 ②l1
节点的下一个节点值 和l2
节点的下一个节点值进行比较。 ③l2
节点的指针指向 ② 的结果。 ④l1
节点指向l2
节点。 ⑤ 返回l1
节点。
迭代循环第 1、2 步,直到 l1
或 l2
节点为 null
复杂度分析
l1 节点数为 n l2 节点数为 m
- 时间复杂度为 O(n)
会遍历每一个节点 (n + m) 进行比较
- 空间复杂度为 O(n)
最多会调用 (n + m) 次函数