剑指 Offer 25. 合并两个排序的链表

169 阅读2分钟

剑指 Offer 25. 合并两个排序的链表

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

1、题目📑

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

实例1

输入:1->2->4, 1->3->4

输出:1->1->2->3->4->4

限制

  • 0 <= 链表长度 <= 1000

注意:本题与主站 21 题相同:leetcode-cn.com/problems/me…

2、思路🧠

方法一:双指针

一般情况下,双指针来解决的链表插入和删除来说是非常的方便,对于数组在某个位置插入和删除非常的繁琐。

  1. 初始化:定义 ListNode l 定义为带头结点的新的链表;定义 ListNode cur 来指向新的链表,用来判断链表 l1,l2 的大小,然后将新链表的下一个节点选择性指向小的。
  2. 循环判断:判断结束条件,两个链表中有一个链表为空,则结束。即 l1 != null && l2 != null
    • 该题目说明两个链表的数字已经是升序排列,通过比较 l1 , l2 的大小来决定cur的指向。
      • 如果 l1.val < l2.val , 将 cur 的下一个节点指向小的,即 l1 ;将 curl1 节点后移;
      • 如果 l1.val >= l2.val , 将 cur 的下一个节点指向小的,即 l2 ;将 curl2 节点后移;
  3. 结束循环之后,将该cur指向链表不为空的节点位置。

方法二:递归

  1. 特判:

    • 如果 l1 == null 则返回链表 l2
    • 如果 l2 == null 则返回链表 l1
  2. 递归判断:

    • 如果 l1 节点值比 l2 大,下一个节点应该是 l2,应该返回 return l2 ,在return之前,需要指定 l2 的下一个节点应该是 l1l2.next 俩链表比较大小返回小的链表的结点;

    • 如果 l1 节点值比 l2 小,下一个节点应该是 l1,应该返回 return l1 ,在return之前,需要指定 l1 的下一个节点应该是l1.nextl2 俩链表比较大小返回小的链表的结点;

废话少说~~~~~上代码!

3、代码👨‍💻

第一次commit AC

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode l = new ListNode(0);
        ListNode cur = l;
        while(l1 != null && l2 != null) {
            if(l1.val < l2.val) {
                cur.next = l1;
                l1 = l1.next;
                cur = cur.next; 
            }else {
                cur.next = l2;
                l2 = l2.next;
                cur = cur.next; 
            }
        }

        cur.next = l1 == null ? l2 : l1;
        return l.next;
    }
}

时间复杂度:O(m + n) m代表链表 l1 的长度,n代表链表 l2 的长度

空间复杂度:O(1)

第二次commit AC

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1 == null) return l2;
        if(l2 == null) return l1;

        if(l1.val > l2.val){
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }else {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        }
    }
}

时间复杂度:O(m + n) m代表链表 l1 的长度,n代表链表 l2 的长度

空间复杂度:O(m + n)

image-20220401235208931

4、总结

该题目的最大难度在于是否理解链表的结构,理解双指针,对于初学者来说双指针是非常头疼的问题。

5、链表的相关操作

链接直达🔗

剑指 Offer 18. 删除链表的节点 - 掘金

剑指 Offer 22. 链表中倒数第k个节点 - 掘金

剑指 Offer 24. 反转链表 - 掘金

Leetcode 21. 合并两个有序链表 - 掘金

Leetcode 83. 删除排序链表中的重复元素 - 掘金

❤️‍来自专栏《LeetCode基础算法题》欢迎订阅❤️‍

厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。

对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!

原题链接:剑指 Offer 25. 合并两个排序的链表