首页 > 代码库 > 【LeetCode】Linked List Cycle II

【LeetCode】Linked List Cycle II

题目

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?

解答

利用快慢指针使用Linked List Cycle I的办法,判断是否有cycle,有环则跳出循环,此时,相遇点离环开始点和链表头到环开始点距离一样,将slow置于表头,fast不变,两者再次相遇就是环的开始点。

如下图分析:


设:链表头是X,环的第一个节点是Y,slow和fast第一次的交点是Z。各段的长度分别是a,b,c,如图所示。环的长度是L。slow和fast的速度分别是qs,qf。

第一次相遇时slow走过的距离:a+b,fast走过的距离:a+b+c+b。

因为fast的速度是slow的两倍,所以fast走的距离是slow的两倍,有 2(a+b) = a+b+c+b,可以得到a=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) {
        if(head==null||head.next==null){
            return null;
        }
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            if(fast==slow){
                break;
            }
        }
        //错误检查,这是无环情况
		if(fast==null||fast.next==null){
			return null;
		}
		//相遇点离环开始点和链表头到环开始点距离一样,将slow置于表头,fast不变,两者再次相遇就是环的开始点
        slow=head;
        while(slow!=fast){
            fast=fast.next;
            slow=slow.next;
        }
        return fast;
    }
}

---EOF---



【LeetCode】Linked List Cycle II