题目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;
}
}