LeetCode 160 – 相交链表

题目描述

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

图示两个链表在节点 c1 开始相交:

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

题目分析

长度差

先遍历一下两个链表的长度,差为 count。
让长的先走 count 步,最后再同步走,直到相遇。
时间复杂度 O(m + n)

拼接

让两个链表相互拼接,得到 A+B 和 B+A。
此时长度是相同的,可以同步进行遍历。
(代码中不需要真的做拼接,手动控制指针的遍历顺序即可)
如果链表相交,会相遇;如果不相交,会同时为null。
时间复杂度 O(m + n)

Java

public ListNode getIntersectionNode1(ListNode headA, ListNode headB) {
    int lengthA = getLength(headA);
    int lengthB = getLength(headB);

    // 确保 A 比较长
    if (lengthB > lengthA) {
        ListNode temp = headB;
        headB = headA;
        headA = temp;
    }
    int count = Math.abs(lengthA - lengthB);
    while (count > 0) {
        headA = headA.next;
        count--;
    }
    while (headA != headB) {
        headA = headA.next;
        headB = headB.next;
    }

    return headA;
}

private int getLength(ListNode node) {
    int length = 0;
    while (node != null) {
        length++;
        node = node.next;
    }
    return length;
}

public ListNode getIntersectionNode2(ListNode headA, ListNode headB) {
    ListNode a = headA, b = headB;
    while(a != b) {
        a = a == null ? headB : a.next;
        b = b == null ? headA : b.next;
    }

    return a;
}

Kotlin

fun getIntersectionNode(headA: ListNode?, headB: ListNode?): ListNode? {
    var a = headA
    var b = headB
    while (a != b) {
        a = if (a == null) headB else a.next
        b = if (b == null) headA else b.next
    }
    return a
}

发表回复

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

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部