LeetCode Linked List Cycle II(Floyd 判圈算法)

题目描述:https://oj.leetcode.com/problems/linked-list-cycle-ii/

首先使用Floyd 判圈算法,可以判断链表是否存在环,然后,还要求出环开始的点。

这里求环开始的点需要一些推导:

设从链表起点到环起点的距离为m,环的周长为s,fastPtr和slowPtr在距离环起点k处相遇。

相遇时slowPtr的运行长度:ls = m+s*n1+k;fastPtr的运行长度 lf =m+s*n2+k。同时注意到,fastPtr的速度是slowPtr的2倍,则 2*ls = lf,则ls = (n2-n1)*s。即ls是圈周长的倍数。在slowPtr和fastPtr相遇后,将slowPtr移动到链表头。slowPtr和fastPtr一同移动,当slowPtr移动到距离链表头m的距离,fastPtr移动到距离链表头i+m的距离。因为i为周长的倍数。这样看,fastPtr相当与从链表头部开始,移动到环的开始(m)处,然后绕了环n圈,回到开始。这样fastPtr和slowPtr的相遇处即是环的开始处。



package Linked_List_Cycle_II;

public class Solution {
	class ListNode{
		int val;
		ListNode next;
		ListNode(int x){
			val = x;
			next = null;
		}
	}
	   public ListNode detectCycle(ListNode head) {
		   if(head==null) return null;
	       ListNode slowPtr = head;
	       ListNode fastPtr = head;
	       boolean flag = true;
	       do{
	    	   if(fastPtr.next == null||fastPtr.next.next == null){
	    		   flag = false;
	    		   break;
	    	   }
	    	   slowPtr = slowPtr.next;
	    	   fastPtr = fastPtr.next;
	    	   fastPtr = fastPtr.next;
	       }while(slowPtr!=fastPtr);
	       if(flag == false )
	    	   return null;
	       else{
	    	   slowPtr = head;
	    	   while(slowPtr != fastPtr){
	    		   slowPtr = slowPtr.next;
	    		   fastPtr = fastPtr.next;
	    	   }
	    	   return slowPtr;
	       }
	    }
}


你可能感兴趣的:(LeetCode)