链表 - 21.合并两个有序链表-双指针方法

91 阅读2分钟

题目21 合并两个有序链表

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

解题思路

CHAGPT: 要将两个升序链表合并为一个新的升序链表,您可以使用双指针方法。这个方法的基本思路是同时遍历两个链表,比较当前两个指针指向的节点,将较小的节点加入到新链表中,然后移动指向较小节点的指针。重复这个过程,直到两个链表中的一个被完全遍历。最后,将未遍历完的链表剩余部分接在新链表后面。

public class ListNode {
    int val;
    ListNode next;
    ListNode() {}
    ListNode(int val) { this.val = val; }
    ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}

public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        // 创建一个哑节点作为新链表的头部
        ListNode dummy = new ListNode(-1);

        // 初始化当前节点为哑节点
        ListNode current = dummy;

        // 遍历两个链表,直到其中一个遍历完成
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                current.next = l1;
                l1 = l1.next;
            } else {
                current.next = l2;
                l2 = l2.next;
            }
            current = current.next;
        }

        // 将未结束的链表接在新链表后面
        current.next = (l1 != null) ? l1 : l2;

        // 返回新链表的头节点
        return dummy.next;
    }
}

YOU:同时你要给出此种结算是否是最优解法 以及 复杂度是多少

CHATGPT:

合并两个升序链表的方法,如我之前提供的双指针法,是解决这个问题的最优解法。这种方法的时间复杂度和空间复杂度都是非常高效的。

时间复杂度: 时间复杂度是 (O(n + m)),其中 (n) 和 (m) 分别是两个链表的长度。这是因为在最坏的情况下,你需要遍历两个链表中的每一个节点一次来比较它们的值。

空间复杂度: 空间复杂度是 (O(1))。我们没有使用额外的空间来存储新链表,而是直接在原有的两个链表上操作,只需要几个额外的指针来跟踪当前位置。

这种方法是最优的,因为它利用了链表已经是升序排列的特点,通过一次遍历就能合并链表。这比其他可能需要更多遍历或额外存储空间的方法更有效率。

官方的最优解

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dum = new ListNode(0), cur = dum;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                cur.next = l1;
                l1 = l1.next;
            } else {
                cur.next = l2;
                l2 = l2.next;
            }
            cur = cur.next;
        }
        cur.next = l1 != null ? l1 : l2;
        return dum.next;
    }
}