1. 程式人生 > >LeetCode 142—環形連結串列 II

LeetCode 142—環形連結串列 II

給定一個連結串列,返回連結串列開始入環的第一個節點。 如果連結串列無環,則返回 null。

說明:不允許修改給定的連結串列。

進階:

你是否可以不用額外空間解決此題?

首先我們看下面這張圖:

設:連結串列頭是X,環的第一個節點是Y,slow和fast第一次的交點是Z。各段的長度分別是a,b,c,如圖所示。環的長度是L。

第一次相遇時slow走過的距離:a+b,fast走過的距離:a+b+c+b。

因為fast的速度是slow的兩倍,所以fast走的距離是slow的兩倍,有 2(a+b) = a+b+c+b,可以得到a=c(這個結論很重要!)。

我們發現L=b+c=a+b,也就是說,從一開始到二者第一次相遇,迴圈的次數就等於環的長度。

我們已經得到了結論a=c,那麼讓兩個指標分別從X和Z開始走,每次走一步,那麼正好會在Y相遇。也就是環的第一個節點。

 public ListNode detectCycle(ListNode head) {
		    if(head==null) return null;
	        ListNode slow=head;
	        ListNode fast=head;
	        while(fast!=null) {
	        	slow=slow.next;
	        	fast=fast.next.next;
	        	if(slow==fast) break;//第一次相遇在Z點

	        }
	        slow=head;//slow從頭開始走
	        while(slow!=fast) {//二者相遇在Y點,則退出
	        	slow=slow.next;
	        	fast=fast.next;
	        }
	        return slow;
	        
	        }