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?
https://oj.leetcode.com/problems/linked-list-cycle-ii/
思路:同参考CC150,相遇之后slow指针移至开头,快慢指针同步前进,相遇点即为圈的开始点。
public class Solution { public ListNode detectCycle(ListNode head) { ListNode slow = head; ListNode fast = head; boolean meet = false; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; if (slow == fast) { meet = true; break; } } if (!meet) return null; slow = head; while (slow != fast) { slow = slow.next; fast = fast.next; } return slow; } public static void main(String[] args) { ListNode head = new ListNode(1); head.next = new ListNode(2); head.next.next = new ListNode(3); head.next.next.next = new ListNode(4); head.next.next.next.next = new ListNode(5); head.next.next.next.next.next = head.next.next; System.out.println(new Solution().detectCycle(head).val); } }
第二遍记录:其实这是个数学题,可以画个图分析下,假设遇到环之前的长度为n,环的周长为m,双指针相遇点为环的第k个元素, 根据fast走的路程是slow的两倍,
列公式 2(m+n) = n+k+m,得出k=m-n,进而可以推出相遇点理环起始点的长度 m-k 为n,意味着相遇点理环开始点的长度与从头出发进入环之前的长度是一样的!
所以我们从相遇点移动一个指针到head上,然后两个指针同步移动,相遇时即为环的开始点。
/** * 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; boolean hasCycle=false; while(fast!=null&&fast.next!=null){ fast = fast.next.next; slow = slow.next; if(fast==slow){ hasCycle=true; break; } } if(!hasCycle) return null; slow =head; while(slow!=fast){ slow=slow.next; fast=fast.next; } return slow; } }
第三遍记录:
太熟练了。。