跳到主要内容

简述Java实现有环单链表判交 ?

参考答案:

在Java中,判断两个有环单链表是否相交(即它们是否共享一个或多个节点)可以通过使用双指针技术来实现。这种技术通常被称为Floyd的循环检测算法或龟兔赛跑算法。以下是一个简单的实现步骤:

  1. 检测链表中的环:首先,需要确保两个链表都包含环。这可以通过使用快慢指针(也称为Floyd检测算法)来完成。快指针每次移动两个节点,慢指针每次移动一个节点。如果链表包含环,快指针最终会追上慢指针。
  2. 寻找相交点:一旦确定两个链表都有环,可以使用一种称为“寻找环内相遇点”的技术来找到它们相交的位置。首先,将两个链表的头节点分别设为两个指针的起始点,并让这两个指针以相同的速度(例如,每次移动一个节点)遍历链表。当它们相遇时,它们将在环中的某个点相遇,这个点也是两个链表相交的位置。

以下是一个示例代码,展示了如何在Java中实现这个过程:

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
        next = null;
    }
}

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) {
            return null;
        }

        // Step 1: Find the cycles and the entry points of the cycles
        ListNode tailA = findTail(headA);
        ListNode tailB = findTail(headB);

        // If the tails are not the same, then there is no intersection
        if (tailA != tailB) {
            return null;
        }

        // Step 2: Move the heads to the entry points of the cycles
        // and let them move with the same speed to find the intersection point
        while (headA != tailA) {
            headA = headA.next;
            tailA = tailA.next;
        }

        while (headB != tailB) {
            headB = headB.next;
            tailB = tailB.next;
        }

        // Step 3: Move the heads with the same speed until they meet
        while (headA != headB) {
            headA = headA.next;
            headB = headB.next;
        }

        return headA; // This is the intersection point
    }

    // Helper function to find the tail (entry point) of a cycle
    private ListNode findTail(ListNode head) {
        if (head == null) {
            return null;
        }

        ListNode slow = head;
        ListNode fast = head;

        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;

            if (slow == fast) {
                break; // Cycle detected
            }
        }

        if (fast == null || fast.next == null) {
            return null; // No cycle detected
        }

        // Move the slow pointer to the beginning of the cycle
        while (head != slow) {
            head = head.next;
            slow = slow.next;
        }

        return head;
    }
}

这个代码示例定义了一个ListNode类来表示链表节点,以及一个Solution类来包含检测链表相交的主要逻辑。getIntersectionNode方法接受两个链表的头节点作为参数,并返回它们的相交节点(如果存在的话)。findTail方法是一个辅助函数,用于检测链表中的环并找到环的入口点。