[LeetCode21.合并两个有序链表] | 刷题打卡

188 阅读2分钟

一、题目描述:

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例 1:

image.png

输入: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 春招闯关活动」, 点击查看活动详情