鏈表有環(huán)問題

問題1: 給定一個(gè)鏈表,判斷這個(gè)鏈表是否有環(huán)

原理:使用快慢指針法,如果鏈表有環(huán),則必定存在兩個(gè)指針相等.

typedef int ElementType;
struct Node{
    ElementType data;
    struct Node* next;
};
typedef struct Node* PNode;
typedef PNode List;

/**
 * 判斷一個(gè)鏈表是否有環(huán)
 * @param list
 * @return 0 :無, 1:有
 */
int existLoop(List list){
    if(list == NULL) return 0;
    PNode fast , slow;
    slow = fast = list;
    while (fast->next != NULL){
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast){
            return 1;
        }
    }
    return 0;
}

問題2: 如果鏈表有環(huán),找出環(huán)的入口節(jié)點(diǎn)

image.png

如上圖所示,依然使用快門指針法(快指針的速度=2 倍慢指針的速度)超凳,當(dāng)兩個(gè)指針第一次相遇時(shí),設(shè)相遇點(diǎn)為X,
M->P:設(shè)為a, P->X:設(shè)為b,X->P設(shè)為c。

首先可以肯定的是剃诅,第一次相遇時(shí),慢指針不可能在環(huán)里運(yùn)動(dòng)超過一圈:
證明:設(shè)慢指針到達(dá)入口p點(diǎn)時(shí)驶忌,快指針在環(huán)內(nèi)的某個(gè)位置P0矛辕,設(shè)環(huán)長(zhǎng)度為m, 則此時(shí)P0->P的距離肯定是小于m的笑跛,當(dāng)慢指針運(yùn)動(dòng)一圈時(shí)走的距離為m, 而快指針此時(shí)走了2m,就是說快指針早就追趕上了慢指針聊品。即兩者相遇時(shí)慢指針不可能運(yùn)動(dòng)超過一圈飞蹂。

有了上面的結(jié)論,我們假設(shè)當(dāng)?shù)谝淮蜗嘤鰰r(shí)翻屈,快指針已經(jīng)在環(huán)里運(yùn)行了n圈陈哑,因此其走的距離為n*(b+c) + b+a,慢指針運(yùn)動(dòng)的距離為a+b, 由于快指針的運(yùn)動(dòng)速度時(shí)慢指針的2倍伸眶,得如下等式

2*(a+b) = n*(b+c)+b +a   =>  a+b=n(b+c)   => a = (n-1)(b+c) + c

從上面的等式關(guān)系惊窖,我們可以得出以下結(jié)論:

  1. 第一次相遇時(shí),慢指針走的距離一定是環(huán)長(zhǎng)度的整數(shù)倍
  2. 第一次相遇后厘贼,若有兩個(gè)速度相同的指針界酒,一個(gè)從M點(diǎn)出發(fā),一個(gè)從X點(diǎn)出發(fā)嘴秸,繼續(xù)運(yùn)動(dòng)毁欣,則二者一定會(huì)在P點(diǎn)發(fā)生相遇。
PNode getEntreLoop(List list){
    if(list == NULL) return 0;
    PNode fast , slow;
    slow = fast = list;
    while (fast->next != NULL){
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast){
            //快慢指針第一次相遇的節(jié)點(diǎn)
            break;
        }
    }
    
    PNode ptr01 = slow , ptr02 = list;
    while (fast->next != NULL){
        ptr01 = ptr01->next;
        ptr02 = ptr02->next;
        if(ptr01 == ptr02){
            printf("\n找到環(huán)的入口點(diǎn):%d\n",ptr02->data);
            return ptr02;
        }
    }
    return NULL;
}

問題3: 環(huán)有多長(zhǎng)

原理:快慢指針第一遍相遇后,然后在進(jìn)行第二遍循,當(dāng)快慢指針再一次相遇時(shí),記錄慢指針走的步數(shù)就是,環(huán)的長(zhǎng)度.

當(dāng)?shù)谝淮蜗嘤龊罅抟牛俅沃匦鲁霭l(fā)署辉,當(dāng)慢指針走了一半時(shí),此時(shí)快指針已經(jīng)完成了一圈岩四,重新回到出發(fā)點(diǎn)哭尝,當(dāng)慢指針完成一圈時(shí),快指針正好完成了第二圈剖煌,此時(shí)二者在相同的相遇點(diǎn)完成了第二次相遇材鹦。

int getLoopLen(List list){
    if(list == NULL) return 0;
    PNode fast , slow;
    slow = fast = list;
    while (fast->next != NULL){
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast){
            //快慢指針第一次相遇的節(jié)點(diǎn)
            break;
        }
    }
 
     int len = 0;   
 
    while (fast->next != NULL){
        len++;
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast){
         //快慢指針第二次相遇的節(jié)點(diǎn)
         return len;
        }
    }
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市耕姊,隨后出現(xiàn)的幾起案子桶唐,更是在濱河造成了極大的恐慌,老刑警劉巖茉兰,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尤泽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡规脸,警方通過查閱死者的電腦和手機(jī)坯约,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來莫鸭,“玉大人闹丐,你說我怎么就攤上這事”灰颍” “怎么了卿拴?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵衫仑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我堕花,道長(zhǎng)文狱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任航徙,我火速辦了婚禮如贷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘到踏。我一直安慰自己,他們只是感情好尚猿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布窝稿。 她就那樣靜靜地躺著,像睡著了一般凿掂。 火紅的嫁衣襯著肌膚如雪伴榔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天庄萎,我揣著相機(jī)與錄音踪少,去河邊找鬼。 笑死糠涛,一個(gè)胖子當(dāng)著我的面吹牛援奢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播忍捡,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼集漾,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了砸脊?” 一聲冷哼從身側(cè)響起具篇,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凌埂,沒想到半個(gè)月后驱显,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞳抓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年埃疫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挨下。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡熔恢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出臭笆,到底是詐尸還是另有隱情导绷,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布文兢,位于F島的核電站塔逃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏盈厘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望孟岛。 院中可真熱鬧,春花似錦督勺、人聲如沸渠羞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽次询。三九已至,卻和暖如春瓷叫,著一層夾襖步出監(jiān)牢的瞬間屯吊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工摹菠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盒卸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓次氨,卻偏偏與公主長(zhǎng)得像蔽介,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子糟需,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 鏈表刪除[203] Remove Linked List Elements[19] Remove Nth Node...
    野狗子嗷嗷嗷閱讀 6,267評(píng)論 4 35
  • 單鏈表 單鏈表問題與思路 找出單鏈表的倒數(shù)第K個(gè)元素(僅允許遍歷一遍鏈表)使用指針追趕的方法屉佳。定義兩個(gè)指針fast...
    wxkkkkk閱讀 599評(píng)論 0 0
  • 搞懂單鏈表常見面試題 Hello 繼上次的 搞懂基本排序算法,這個(gè)一星期洲押,我總結(jié)了武花,我所學(xué)習(xí)和思考的單鏈表基礎(chǔ)知識(shí)...
    醒著的碼者閱讀 4,579評(píng)論 1 45
  • 大學(xué)的時(shí)候不好好學(xué)習(xí),老師在講臺(tái)上講課杈帐,自己在以為老師看不到的座位看小說体箕,現(xiàn)在用到了老師講的知識(shí),只能自己看書查資...
    和玨貓閱讀 1,436評(píng)論 1 3
  • 轉(zhuǎn)載請(qǐng)注明出處:http://www.reibang.com/p/c65d9d753c31 在上一篇博客《數(shù)據(jù)結(jié)構(gòu)...
    Alent閱讀 3,500評(píng)論 4 74