简述Java实现有环单链表判交 ?
参考答案:
在Java中,判断两个有环单链表是否相交(即它们是否共享一个或多个节点)可以通过使用双指针技术来实现。这种技术通常被称为Floyd的循环检测算法或龟兔赛跑算法。以下是一个简单的实现步骤:
- 检测链表中的环:首先,需要确保两个链表都包含环。这可以通过使用快慢指针(也称为Floyd检测算法)来完成。快指针每次移动两个节点,慢指针每次移动一个节点。如果链表包含环,快指针最终会追上慢指针。
- 寻找相交点:一旦确定两个链表都有环,可以使用一种称为“寻找环内相遇点”的技术来找到它们相交的位置。首先,将两个链表的头节点分别设为两个指针的起始点,并让这两个指针以相同的速度(例如,每次移动一个节点)遍历链表。当它们相遇时,它们将在环中的某个点相遇,这个点也是两个链表相交的位置。
以下是一个示例代码,展示了如何在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
方法是一个辅助函数,用于检测链表中的环并找到环的入口点。