一、题目描述:
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
二、思路分析:
两种解法,递归和迭代。 迭代:
- 创建一个合并链表的前驱结点和head结点
- 一起遍历l1和l2,比较l1和l2的值大小,将较小的结点接到head后面,并且head向后滚动
- 最后把l1或者l2剩下的部分接到head指针后面
- 返回前驱结点的next
递归: 如果 l1 或者 l2 一开始就是空链表 ,那么没有任何操作需要合并,所以我们只需要返回非空链表。否则,我们要判断 l1 和 l2 哪一个链表的头节点的值更小,然后递归地决定下一个添加到结果里的节点。如果两个链表有一个为空,递归结束。
时间复杂度都是O(n+m),空间复杂度递归是O(n+m),迭代是O(1)
三、AC 代码:
class Solution {
fun mergeTwoLists(l1: ListNode?, l2: ListNode?): ListNode? {
return solution2(l1, l2)
}
fun solution2(l1: ListNode?, l2: ListNode?): ListNode? {
if (l1 == null) {
return l2
} else if (l2 == null) {
return l1
} else if (l1.`val` < l2.`val`) {
l1.next = solution2(l1.next, l2)
return l1
} else {
l2.next = solution2(l1, l2.next)
return l2
}
}
// 迭代
fun solution1(l1: ListNode?, l2: ListNode?): ListNode? {
var head: ListNode? = ListNode(-1)
var p = l1
var q = l2
var result = head
while (p != null && q != null) {
if (p.`val` < q.`val`) {
head?.next = p
p = p.next
} else {
head?.next = q
q = q.next
}
head = head?.next
}
if (p != null) {
head?.next = p
} else {
head?.next = q
}
return result?.next
}
}
四、总结:
好像这类链表题都可以用递归做。只是不太好想
本文正在参与「掘金 2021 春招闯关活动」, 点击查看活动详情