链表中环的入口节点
思路: 快慢指针
快指针一次两步,慢指针一次一步,如果链表中有环,则快指针必会与慢指针相遇。如果无环,则快指针会先指向 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; } }
快慢指针使用的很频繁,一定要掌握。