Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.
Follow up:
Can you solve it without using extra space?
这题类似于检测环路,关键是求得环的长度。自己想出了一个O(n))的快慢指针解法,该解法需要让两个指针一共相遇3次。
1) 先检测是否存在环,如果存在,那么快慢指针相遇地点比为环内。
2) 如果存在环,那么让其中任意一个指针再往下继续走,而另一个指针不动,直到两指针再次相遇。可以知道其中一个指针走的距离是环的长度,标记为L。
3) 让两个指针同时回到表头,并且让一个指针先走L长度,使得两指针的间距为L。然后让两指针同速走直到相遇。相遇地点即为所求的环的起始节点。
public ListNode detectCycle(ListNode head) { ListNode slow = head, fast = head; // 1st Meet: find the meeting point while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; if (slow == fast) break; } // error check - no meeting point if (fast == null || fast.next == null) return null; // 2nd Meet: calculate the length of the cycle int cycleLen = 0; do { slow = slow.next; cycleLen++; } while (slow != fast); // 3rd Meet: find the beginning slow = fast = head; for (int i = 0; i < cycleLen; i++) { fast = fast.next; } while (fast != slow) { fast = fast.next; slow = slow.next; } return fast; }