1. 程式人生 > >劍指offer--連結串列中環的入口結點

劍指offer--連結串列中環的入口結點

題目描述

一個連結串列中包含環,請找出該連結串列的環的入口結點。
分析:

如果存在環,找到環的起始結點

當fast指標等於slow指標時,slow指標肯定還沒有遍歷完整個連結串列,而此時fast指標已經在環內迴圈了n圈(n>=1),假定從連結串列頭指標開始slow走了s步,則fast走了2s步,fast所走的步數還等於s加上fast指標比slow指標在環內多走的n圈。設環長為r,則:

2s = s + nr;

=>s = nr;

設整個連結串列長度為L,環的入口結點到相遇結點的距離為x, 起點到環的入口結點的距離為a.

a + x = nr;

=> a + x = (n-1)r + L - a;

=> a = (n-1)r + (L - a - x);

=> 由連結串列的頭結點到環入口結點的距離等於n-1圈環的長度+相遇點到環入口結點的距離,於是,當我們在連結串列頭部和相遇處分別設一指標,每次各走一步,則兩指標必定相遇,且相遇的第一個結點即為環的入口結點

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {

	ListNode EntryNodeOfLoop(ListNode pHead)
	{
		if (pHead == null || pHead.next == null) {
             return null;
         }
         ListNode fast = new ListNode(0);
         ListNode slow = new ListNode(0);
         slow = pHead.next;
         fast = pHead.next.next;
         while (fast != slow) {
             slow = slow.next;
             fast = fast.next.next;
         }
         fast = pHead;
         while (fast != null) {
             if (fast == slow) {
                 return fast;
             }
             slow = slow.next;
             fast = fast.next;
         }
         return slow;
	}
}