21.合并两个有序链表

157 阅读2分钟

1.题目

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

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4] 输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = [] 输出:[]

示例 3:

输入:l1 = [], l2 = [0] 输出:[0]

提示:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1 和 l2 均按 非递减顺序 排列

2.答题

思路1:

  • 两个l1和l2指针,分别向后循环链表
  • 比较链表的值,如果l1小,插入l1的值,指针后移,如果l2小,插入l2的值,指针后移
  • 插入指针还未指到最后的链表

代码如下:

public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummyNode = new ListNode(-1);//哨兵结点
        ListNode head = dummyNode;
​
        while(l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                head.next = l1;
                l1 = l1.next;
            } else {
                head.next = l2;
                l2 = l2.next;
            }
            head = head.next;
        }
​
        if (l1.next != null) {
            head.next = l1.next;
        }
​
        if (l2.next != null) {
            head.next = l2.next;
        }
​
        return dummyNode.next;
    }
}
​

时间复杂度

遍历两个链表O(m+n)

空间复杂度

产生了一个新的链表用于存储原链表,复杂度为O(m+n)

提交结果

提交结果1.png

链表的基本操作,优化的话可以考虑使用l1或l2直接操作,不生成新链表,节省一部分。

思路2:

  • 两个l1和l2指针,分别向后循环链表
  • 比较链表的值,如果l1小,l1指针后移,如果l2小,在l1中插入l2的值,指针后移
  • 若l1已经到达最后,l1指针直接指向l2

代码如下:

public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummyNode = new ListNode(-1);
        dummyNode.next = l1;
​
        ListNode head = dummyNode;
​
        while(l2 != null) {
            if (l1 == null) {
                head.next = l2;
                break;
            }
​
            if (l1.val <= l2.val) {
                l1 = l1.next;
            } else {
                ListNode tmp = head.next;
                head.next = l2;
                l2 = l2.next;
                head.next.next = tmp;
            }
            head = head.next;
        }
​
        return dummyNode.next;
    }
}
​

时间复杂度

遍历两个链表O(m+n)

空间复杂度

在l1的基础上扩容了l1,复杂度为O(n)对比之前应该是O(m+n)

提交结果

提交结果2.png

错误指出,好的方法欢迎留言。