大厂面试手撕面试题:合并两个有序链表(亲测可用的java实现)

在面试中,合并两个有序链表的题目是非常常见的。这个问题的关键是利用两个链表的有序性来高效地合并它们。

思路:

  1. 初始化两个指针:
    • 一个指针指向链表A的头节点,另一个指针指向链表B的头节点。
  2. 比较两个指针所指向的节点值:
    • 比较当前两个节点的值,将较小的节点添加到新的链表中。
    • 然后,移动对应指针到下一个节点,继续比较。
  3. 处理剩余的部分:
    • 当其中一个链表的节点全部合并到新链表后,直接将另一个链表的剩余部分连接到新链表上。
  4. 返回结果:
    • 合并完成后返回新链表的头节点。

时间复杂度:

  • 每个链表的节点都需要访问一次,时间复杂度为 �(�+�)O(n+m),其中 �n 和 �m 分别是两个链表的长度。

空间复杂度:

  • 空间复杂度为 �(1)O(1),因为我们是在原地合并链表,没有使用额外的空间(除了新链表的头节点指针)。

Java代码实现:

// Definition for singly-linked list.
class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        // 创建一个虚拟头节点,简化处理
        ListNode dummy = new ListNode(0);
        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;
        }
        
        // 如果有一个链表还剩余节点,直接连接到合并链表的尾部
        if (l1 != null) {
            current.next = l1;
        } else if (l2 != null) {
            current.next = l2;
        }
        
        // 返回合并后的链表,跳过虚拟头节点
        return dummy.next;
    }
}

代码解析:

  1. ListNode类: 这是链表节点的定义,每个节点包含一个整数值和一个指向下一个节点的指针。
  2. mergeTwoLists方法:
    • dummy 是一个虚拟的头节点,它用于简化处理过程,最终返回合并后的链表。
    • current 用来追踪合并链表的最后一个节点。
    • 在 while 循环中,比较 l1 和 l2 的当前节点,选择较小的节点并将其加入到合并链表中。然后,继续移动指针。
    • 当一个链表结束时,直接将另一个链表剩余的部分连接到合并链表。
  3. 返回结果: 最后返回 dummy.next,这是合并后的链表的头节点。

关注公众号“大模型全栈程序员”回复“小程序”获取1000个小程序打包源码。更多免费资源在http://www.gitweixin.com/?p=2627

发表评论

邮箱地址不会被公开。 必填项已用*标注