求單鏈表是否有環、環長、入環點、鏈長

1. 單鏈表是否有環

用兩個快慢指針去判斷單鏈表是否環,快指針的速度是慢指針的兩倍,若單鏈表有環,則兩個指針會先後進入環內,並且快指針會從後面追上慢指針。下面來嚴謹地分析一下兩個指針在環內相遇的情況。
假設此時慢指針s和快指針f都在環內,相隔k點,環內共有R點,t時間之後,兩指針相遇。

[快指針最終位置 = 慢指針最終位置] -> [(2t mod R) + k = (t mod R)] 假設 2t = aR + x, t = bR + y, a > b
-> 2t - aR + k = t - bR
-> t = (a - b)R - k

這裏寫圖片描述

typedef struct node{
    int value;
    node *next;
}node_t;

int testloop(node_t *head)
{
    node_t *fast = head;
    node_t *slow = head;
    while(fast->next != null && fast->next->next != null) {
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast) {
            return -1;//have loop
        }
    }
    return 0;//no loop
}

2. 求環長度

t = (a - b)n - k

我們在上面推導出在環內相遇要經過的時間t,那麼現在從第一次相遇(k=0)開始算,一直到第二次相遇,慢指針剛好走過一個環長n,即環長等於第一次相遇到第二次相遇,慢指針走的長度。

3. 求入環口

假設第一次相遇點離入環口的距離是x,那麼
快指針走的距離:2s = y + nR + x
慢指針走的距離:s = y + x (慢指針在第一次相遇時,不會走到完整的一環)

-> y = nR - x (n不一定是1,環內的指針可能要轉幾圈纔會和環外的指針相遇)

那麼我們在第一次相遇時,把慢指針留在原地,把快指針放回起點head處,然後把快指針變爲慢指針,兩個指針一起以速度1前進,當它們相遇時,相遇點就是入環點4
這裏寫圖片描述

4. 求鏈長度

問題2求出環長,問題3求出入環點即y的長度,那麼鏈長只要將它們相加即可。

【Reference】
1.http://www.cnblogs.com/xudong-bupt/p/3667729.html
2.http://www.cnblogs.com/kqingchao/archive/2011/07/06/whether_there_is_a_loop_in_link.html

發佈了98 篇原創文章 · 獲贊 41 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章