★ Linked List Cycle II -- LeetCode
證明單鏈表有環路:
本文所用的算法 能夠 形象的比喻就是在操場其中跑步。速度快的會把速度慢的扣圈?
能夠證明,p2追趕上p1的時候。p1一定還沒有走完一遍環路,p2也不會跨越p1多圈才追上?
我們能夠從p2和p1的位置差距來證明。p2一定會趕上p1可是不會跳過p1的?
由于p2每次走2步。而p1走一步。所以他們之間的差距是一步一步的縮小,4,3,2,1,0?
到0的時候就重合了。
找到環路的起點:
既然可以推斷出是否是有環路,那改怎樣找到這個環路的入口呢??
解法例如以下: 當p2依照每次2步,p1每次一步的方式走,發現p2和p1重合,確定了單向鏈表有?????????????????????????????????????? ?
環路了。
接下來。讓p2回到鏈表的頭部。又一次走,每次步長不是走2了,而是走1。那么當p1和p2再次?
相遇的時候。就是環路的入口了。?
這點能夠證明的:?
在p2和p1第一次相遇的時候,假定p1走了n步驟,環路的入口是在p步的時候經過的,那么有?
1、p1走的路徑: p+c = n;??????? c為p1和p2相交點,距離環路入口的距離。
2、p2走的路徑: p+c+k*L = 2*n。? L為環路的周長,k是整數;?
將1式中的p+c=n代入到2式,整理得:n=k*L;
所以,假設從p+c點開始,p1再走n步驟的話,還能夠回到p+c這個點?
同一時候p2從頭開始走的話。經過n不,也會達到p+c這點?
顯然在這個步驟其中p1和p2僅僅有前p步驟走的路徑不同,所以當p1和p2再次重合的時候。必?
然是在鏈表的環路入口點上。?
code
//Given a linked list, return the node where the cycle begins. If there is no cycle, return null. #include<iostream> #include<fstream> using namespace std;struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {} };class Solution { public:ListNode *detectCycle(ListNode *head) {ListNode* fast_walker = head;if (has_cycle(head, fast_walker)){ListNode* cur = head;while (fast_walker != cur){fast_walker = fast_walker->next;cur = cur->next;}return cur;}else return NULL;} private:bool has_cycle(ListNode* head , ListNode* fast_walker){ListNode* slow_walker = head;while (slow_walker && fast_walker){fast_walker = fast_walker->next;if (fast_walker) fast_walker = fast_walker->next;else break;slow_walker = slow_walker->next;if (fast_walker == slow_walker) return true;}return false;} };int main(){fstream fin("test.txt");ListNode* head(0);//此時并沒有分配存儲地址ListNode* tmp = head;//此時相當于 tmp = NULLint in = 0;while (fin >> in){if (!head) {head = new ListNode(in);tmp = head;}else{while (tmp->next != NULL) tmp = tmp->next;tmp->next = new ListNode(in);tmp = tmp->next;tmp->next = NULL;}}//制造一個環tmp->next = head->next;Solution ss;ListNode* retult = ss.detectCycle(head);system("pause");return 0; }總結
以上是生活随笔為你收集整理的★ Linked List Cycle II -- LeetCode的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL二进制日志操作
- 下一篇: redhat server 5.3内核升