劍指offer 連結串列中環的入口結點(詳細分析過程)
阿新 • • 發佈:2019-02-01
思路:
題目描述
一個連結串列中包含環,請找出該連結串列的環的入口結點。來源:牛客網兩個結論: 1、設定快慢指標,假如有環,他們最後一定相遇。 2、兩個指標分別從連結串列頭和相遇點繼續出發,每次走一步,最後一定相遇與環入口。
證明1:設定快慢指標fast和low,fast每次走兩步,low每次走一步。假如有環,兩者一定會相遇(因為low一旦進環,可看作fast在後面追趕low的過程,每次兩者都接近一步,最後一定能追上)。 證明2:
設: 連結串列頭到環入口長度為--a 環入口到相遇點長度為--b 相遇點到環入口長度為--c
則:相遇時 快指標路程=a+(b+c)k+b ,k>=1 其中b+c為環的長度,k為繞環的圈數(k>=1,即最少一圈,不能是0圈,不然和慢指標走的一樣長,矛盾)。 慢指標路程=a+b 快指標走的路程是慢指標的兩倍,所以: (a+b)*2=a+(b+c)k+b 化簡可得: a=(k-1)(b+c)+c 這個式子的意思是: 連結串列頭到環入口的距離=相遇點到環入口的距離+(k-1)圈環長度。其中k>=1,所以k-1>=0圈。所以兩個指標分別從連結串列頭和相遇點出發,最後一定相遇於環入口。
程式碼:
class Solution { public: ListNode* EntryNodeOfLoop(ListNode* pHead) { ListNode*fast=pHead,*low=pHead; while(fast&&fast->next){ fast=fast->next->next; low=low->next; if(fast==low) break; } if(!fast||!fast->next)return NULL; low=pHead; while(fast!=low){ fast=fast->next; low=low->next; } return low; } };