找出有環連結串列中環的起始節點
阿新 • • 發佈:2019-02-13
給定一個有環的連結串列,寫一個演算法,找出環的起點。
例如:
輸入:A->B->C->D->E->C[與前面的C是同一個節點]
輸出:C
判斷一個連結串列是否存在環有一個簡單的方法,就是使用一個快指標、和一個慢指標,快指標每次走兩步,慢指標每次走一步,則如果有環,它們最後必然會相遇的。本題的難點在於要找出環的起點。其實也不難,與判斷是否有環類似,用兩個步長分別為1和2的指標遍歷連結串列,直到兩者相遇,此時慢指標走過的長度就是環的長度。另外相遇後把其中指標重新設定為起始點,讓兩個指標以步長1再走一遍連結串列,相遇點就是環的起始點。
證明也很簡單,證明如下:
我們注意到第一次相遇時
慢指標走過的路程S1 = 非環部分長度 + 弧A長
快指標走過的路程S2 = 非環部分長度 + n * 環長 + 弧A長
S1 * 2 = S2,可得 非環部分長度 = n * 環長 - 弧A長
讓指標A回到起始點後,走過一個非環部分長度,指標B走過了相等的長度,也就是n * 環長 - 弧A長,正好回到環的開頭。
ListNode *findcyclehead(ListNode *head){ ListNode *mp=head; ListNode *kp=head; while(kp->next!=NULL && kp!=mp){ kp=kp->next->next; mp=mp->next; } if(kp->next==NULL) return NULL; mp=head; while(kp!=mp){ kp=kp->next; mp=mp->next; } return kp; }