原題地址:http://oj.leetcode.com/problems/linked-list-cycle-ii/
題意:如果鏈表中存在環路,找到環路的起點節點。
解題思路:這道題有點意思。首先使用快慢指針技巧,如果fast指針和slow指針相遇,則說明鏈表存在環路。具體技巧參見上一篇http://www.cnblogs.com/zuoyuan/p/3701639.html
在fast指針和slow指針相遇后,fast指針不動,slow指針回到head,然后slow指針和fast指針同時向前走,只不過這一次兩個指針都是一步一步向前走。兩個指針相遇的節點就是環路的起點。
示意圖:
原理說明:圖中,head到環路起點的距離為K,起點到fast和slow的相遇點的距離為M,環路周長為L。假設,在fast和slow相遇時,fast走過了Lfast,slow走過了Lslow。根據題意:
Lslow=K+M;Lfast=K+M+n*L(n為正整數);Lfast=2*Lslow
可以推出:Lslow=n*L;K=n*L-M
則當slow重新回到head,而fast還在相遇點,slow和fast都向前走,且每次走一個節點。
則slow從head走到起點走了K,而fast從相遇點出發也走了K,而fast向前走了距離K后到了哪里呢?由於K=(n-1)*L+(L-M),所以fast轉了n-1圈,再走L-M,也到了起點。這樣起點就找到了。
代碼:
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: # @param head, a ListNode # @return a list node def detectCycle(self, head): if head == None or head.next == None: return None slow = fast = head while fast and fast.next: slow = slow.next fast = fast.next.next if fast == slow: break if slow == fast: slow = head while slow != fast: slow = slow.next fast = fast.next return slow return None