链表中环的入口节点

 

 

 思路: 快慢指针

  快指针一次两步,慢指针一次一步,如果链表中有环,则快指针必会与慢指针相遇。如果无环,则快指针会先指向 null,返回 null 即可。

  当他们相遇时,如下图所示。从起点到环的入口节点长度为 a,入口节点到快慢指针相遇点为 X,X到环入口节点的长度为 c。

 

相遇时,快指针走了2(a+b),慢指针走了b + a+n(b+c),即2(a+b) = a+b +n(c+b)

因此 a = (n-1)(c+b)+c

此时头节点与慢节点一起一次一步运动,当头节点运动至环入口节点时,由于a = (n-1)(b+c) +c,此时慢节点也走到环入口节点处,二者相遇。

此时返回慢节点指向位置即可。

代码:

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow) {
                while (head != slow) {
                    slow = slow.next;
                    head = head.next;
                }
                return slow;
            }
        }
        return null;
    }
}

  快慢指针使用的很频繁,一定要掌握。

posted @ 2021-03-08 22:57  zjcfrancis  阅读(89)  评论(0编辑  收藏  举报