[Sword refers to offer] The node of the ring entry in the linked list

Title description:

For a linked list, if it contains a ring, please find the entry node of the ring of the linked list, otherwise, output null.

Problem-solving ideas:


Fast and slow pointer solution: For this problem, we can use a two-pointer solution, one fast and one slow pointer.
The fast pointer runs two elements at a time, and the slow pointer runs one at a time. If there is a circle, one day, the fast pointer will be able to catch up with the slow pointer.
As shown in the figure below, we first find the point where the fast and slow pointers meet, p. Let us further assume that the entry of the ring is at point q, the distance from the head node to point q is A, the distance between two points qp is B, and the distance between two points pq is C.
Because the fast pointer is twice as fast as the slow pointer, and they meet at point p, we can get equation 2(A+B) = A+B+C+B. (If the linked list in front of the ring is very long and the ring is short , Then the fast pointer may turn several times after entering the ring (assuming n turns) before it meets the slow pointer. But in any case, the slow pointer will meet the fast when it enters the first circle of the ring. The equation should be corrected. 2(A+B)= A+ nB + (n-1)C) From the equation of 3, we can get that C = A.
At this time, because our slow pointer is already at p, we can create a new pointer, slow2, and let him start from the head node, and only go to the next one each time. The original slow pointer continues to keep the original way, the same as slow2. Only go next one at a time.
We look forward to the encounter between slow2 and the original slow pointer, because we know that A=C, so when they meet, it must be q.
We can return to either slow2 or slow, because they are pointing to the same node at the moment, which is the starting point of the ring, q.
Insert picture description here

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    
    

    public ListNode EntryNodeOfLoop(ListNode pHead) {
    
    
        ListNode fast = pHead;
        ListNode slow = pHead;
        while(fast != null && fast.next != null ) {
    
    
            fast = fast.next.next;
            slow = slow.next;
            if(slow == fast) {
    
    
                ListNode slow2 = pHead;
                while(slow != slow2) {
    
    
                    slow2 = slow2.next;
                    slow = slow.next;
                }
                return slow;
            }
        }
        return null;
    }
}

Guess you like

Origin blog.csdn.net/qq_45621376/article/details/114648830