鏈表相交問題

判斷兩個單向鏈表是否相交,并找出他們的交點。
這個問題我們分三種情況討論:

一. 兩個鏈表都不存在環

問題思路:

  1. 遍歷兩個鏈表,在遍歷的過程中進行比較,看節點是否相同。
  2. 先遍歷第一個鏈表到他的尾部,然后將尾部的next指針指向第二個鏈表。這樣兩個鏈表就合成了一個鏈表,判斷原來的兩個鏈表是否相交也就轉變成了判斷新的鏈表是否有環的問題了。 如果新的鏈表有環則第二個鏈表從頭節點遍歷一定存在環。


    圖片.png
  3. 如果兩個沒有環的鏈表相交,則這兩個鏈表的尾節點一定相等。因此這種方式判斷兩個鏈表是否相交,就分別遍歷兩個鏈表到尾部,判斷是否相等,如果相等就是相交,否則不相交。
圖片.png

第三那種情況的代碼實現思路:
假設第一個鏈表長度為len1,第二個問len2,然后找出長度較長的,讓長度較長的鏈表指針向后移動|len1 - len2| (len1-len2的絕對值),然后在開始遍歷兩個鏈表,判斷節點是否相同即可。代碼如下

//鏈表節點的定義
typedef struct Node {
    int data;
    struct Node *pNext;
} NODE, *PNODE;


PNODE *findNode(PNODE head1, PNODE head2) {

    if (head1 == NULL || head2 == NULL) {
        //如果鏈表為空則很定不相交
        return NULL;
    }
    PNODE p1, p2;
    p1 = head1;
    p2 = head2;
    int len1 = 0; //第一個鏈表的長度
    int len2 = 0; //第二個鏈表的長度
    int diff = 0;
    while (NULL != p1->pNext) {
        p1 = p1->pNext;
        len1++;
    }
    while (NULL != p2->pNext) {
        p2 = p2->pNext;
        len2++;
    }
    if (p1 != p2) {
        //如果最后一個節點不相同則返回NULL
        return NULL;
    }
    diff = abs(len1 - len2);
    if (len1 > len2) {
        p1 = head1;
        p2 = head2;
    } else {
        p1 = head2;
        p2 = head1;
    }
    for (int i = 0; i < diff; i++) {
        p1 = p1->pNext;
    }
    while (p1 != p2) {
        p1 = p1->pNext;
        p2 = p2->pNext;
    }
    return p1;
}

二. 如果一個鏈表中有環,另一個鏈表沒有環。

這種情況則兩個鏈表一定不相交。因為一旦相交則另一個鏈表,一定存在環。

圖片.png

三. 鏈表中有環

  1. 判斷鏈表是否存在環,辦法為:設置兩個指針(fast, slow),初始值都指向頭,slow每次前進一步,fast每次前進二步,如果鏈表存在環,則fast必定先進入環,而slow后進入環,兩個指針必定相遇。(當然,fast先行頭到尾部為NULL,則為無環鏈表)程序如下:
bool IsExitsLoop(slist *head){
    slist *slow = head, *fast = head;
    while ( fast && fast->next )     {
        slow = slow->next;
        fast = fast->next->next;
        if ( slow == fast ) break;
    }
    return !(fast == NULL || fast->next == NULL);
}

二、找到環的入口點當fast若與slow相遇時,slow肯定沒有走遍歷完鏈表,而fast已經在環內循環了n圈(1<=n)。假設slow走了s步,則fast走了2s步(fast步數還等于s 加上在環上多轉的n圈),設環長為r,則:2s = s + nrs= nr設整個鏈表長L,入口環與相遇點距離為x,起點到環入口點的距離為a。a + x = nra + x = (n – 1)r +r = (n-1)r + L - aa = (n-1)r + (L – a – x)(L – a – x)為相遇點到環入口點的距離,由此可知,從鏈表頭到環入口點等于(n-1)循環內環+相遇點到環入口點,于是我們從鏈表頭、與相遇點分別設一個指針,每次各走一步,兩個指針必定相遇,且相遇第一點為環入口點。程序描述如下:

slist* FindLoopPort(slist *head){
    slist *slow = head, *fast = head;
    while ( fast && fast->next )     {
        slow = slow->next;
        fast = fast->next->next;
        if ( slow == fast ) break;
    }    if (fast == NULL || fast->next == NULL)
        return NULL;    slow = head;
    while (slow != fast)    {
        slow = slow->next;
        fast = fast->next;
    }
    return slow;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內容

  • //leetcode中還有花樣鏈表題,這里幾個例子,冰山一角 求單鏈表中結點的個數----時間復雜度O(n)這是最...
    暗黑破壞球嘿哈閱讀 1,528評論 0 6
  • 問題描述問題一: 如何判斷一個鏈表是否有環,如果有, 則返回第一個進入環的節點, 沒有則返回null.問題二: 如...
    周肅閱讀 2,946評論 3 2
  • 推薦大家看下《編程之美》、《程序員面試金典》 還有編程相關網站:leetcode老師講的很多題其實就是這些書和網...
    偷天神貓閱讀 1,282評論 0 6
  • 2. Add Two Numbers 先初始化兩個結點,一個用來做head,一個作為指引node不斷向下延續的指針...
    Morphiaaa閱讀 928評論 0 0
  • 給出兩個單向鏈表的頭指針,而兩個鏈表都可能帶環,判斷這兩個鏈表是否相交,并且給出他們相交的第一個節點 參考 1)判...
    zcwfeng閱讀 430評論 0 1