国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

算法通關(guān)村第一關(guān)——鏈表經(jīng)典問題之第一個公共子節(jié)點筆記

這篇具有很好參考價值的文章主要介紹了算法通關(guān)村第一關(guān)——鏈表經(jīng)典問題之第一個公共子節(jié)點筆記。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

五種方法解決鏈表的第一個公共子節(jié)點問題

題目:劍指 Offer 52. 兩個鏈表的第一個公共節(jié)點

輸入兩個鏈表,找出它們的第一個公共節(jié)點。

如下面的兩個鏈表:
算法通關(guān)村第一關(guān)——鏈表經(jīng)典問題之第一個公共子節(jié)點筆記,算法,鏈表,筆記在節(jié)點 c1 開始相交。

鏈表節(jié)點的定義

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

小技巧:

如果題目剛拿到手的時候沒有思路怎么辦?

試著將常用的數(shù)據(jù)結(jié)構(gòu)和常用的算法思想都想一遍,一個一個靠,看有沒有能解決的。

常用的數(shù)據(jù)結(jié)構(gòu):數(shù)組,鏈表,隊列,棧,Hash表,集合,樹,堆等等

常用的算法:各種排序,雙指針,遞歸等等

按照這個思路,想一想

(1)方法一: 首先想到的就是暴力破解,用一個雙層循環(huán)遍歷來一個一個對比找相同的那個節(jié)點,這樣時間復(fù)雜度就會有點高,O(n^2)

(2)方法二: 既然時間復(fù)雜度比較高的話,那我們就想想用空間換時間,數(shù)組?鏈表?隊列?棧?

欸,這個可以。既然兩個鏈表尾巴是一致的,那將兩個鏈表分別放到棧里面,根據(jù)棧先進(jìn)后出的特性,相當(dāng)于就是從尾到頭地遍歷鏈表嘛。

在出棧過程中,對比兩邊的節(jié)點,若相同則繼續(xù)出棧比較,若不相同,則上一個出棧的節(jié)點就是公共節(jié)點。

這樣時間復(fù)雜度就降到O(n),空間復(fù)雜度為O(n)

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        // 將鏈表A存放到棧A中
        stack<ListNode*> stackA;
        while (headA != nullptr) {
            stackA.push(headA);
            headA = headA->next;
        }
        
        // 將鏈表B存放到棧B中
        stack<ListNode*> stackB;
        while (headB != nullptr) {
            stackB.push(headB);
            headB = headB->next;
        }
        
        ListNode* intersectionNode = nullptr;
        ListNode* tempA = nullptr;
        ListNode* tempB = nullptr;
        
        // 同時出棧進(jìn)行比較
        while(!stackA.empty() && !stackB.empty()) {
            tempA = stackA.top();
            tempB = stackB.top();
            stackA.pop();
            stackB.pop();
            
            // 當(dāng)遇到不一樣的節(jié)點時,證明上一個出棧的即為公共節(jié)點,就是當(dāng)前節(jié)點的下一個節(jié)點
            if (tempA != tempB) {
                break;
            }
        }
        
        // 結(jié)束while的可能性有兩種:
        // 1. 碰到了不同的節(jié)點
        if(tempA != tempB) {
            intersectionNode = tempA->next;
        } else { // 2. A和B所有節(jié)點都是相同的,也就是棧A和棧B同時為空
            intersectionNode = tempA;
        }
        
        return intersectionNode;
    }
};

(3)方法三: 還有沒有其他的數(shù)據(jù)結(jié)構(gòu)能用呢?Hash表和集合?

可以,只將一個鏈表中的節(jié)點存到hash表或者集合中,然后遍歷另外一個鏈表,看有沒有集合中有沒有一樣的節(jié)點。

時間復(fù)雜度為O(n),空間復(fù)雜度為O(n)

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
       set<ListNode*> setA;
       while(headA != nullptr) {
           setA.insert(headA);
           headA = headA->next;
       }
        
        while (headB != nullptr) {
            if (setA.find(headB) != setA.end()) {
                return headB;
            }
            headB = headB->next;
        }
        
        return nullptr;
    }
};

那還有沒有時間或者空間復(fù)雜度更低的方法呢?一般這個時候,想要的方法都是稍微帶一點技巧性了,多刷題的重要性在此時此刻就體現(xiàn)出來了。

(4)方法四: 拼接法,既然兩個鏈表最后的部分都是一樣的。那我們將兩個鏈表拼一下,就像A和B,我們拼成AB和BA兩種,然后進(jìn)行遍歷,最后肯定會在某一個節(jié)點達(dá)成相同的。

注意,我們是為了減少空間復(fù)雜度來跟進(jìn)一步地找方法的,如果我們又去新建兩個鏈表豈不是違背初衷了嘛?

那我們怎么辦呢?

欸,我們只需要在遍歷完A后,接著遍歷B,不就組成AB了。同樣遍歷B,再遍歷A,就組成BA了。而且,一邊遍歷一邊比較,這樣就OK啦!

算法通關(guān)村第一關(guān)——鏈表經(jīng)典問題之第一個公共子節(jié)點筆記,算法,鏈表,筆記

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if (headA == nullptr || headB == nullptr) {
            return nullptr;
        }
        
        ListNode* pA = headA;
        ListNode* pB = headB;
        
        // 當(dāng)不為公共節(jié)點時,就接著往下遍歷
        while (pA != pB) {
            pA = pA->next;
            pB = pB->next;
            
            /* 考慮邊界條件,那就是沒有公共節(jié)點的時候
             * 在更新pA和pB之后,如果pA == pB == nullptr
             * 就意味著AB和BA對比完了,那我們就不能繼續(xù)下去
             * 否則會導(dǎo)致ABABABAB……和BABABABA……無限下去造成死循環(huán)了
             * */
            if (pA != pB) {
                // 拼成AB,當(dāng)A遍歷完了,就接著遍歷B
                if (pA == nullptr) { 
                	pA = headB;
            	}
                
                // 拼成BA,當(dāng)B遍歷完了,就接著遍歷A
            	if (pB == nullptr) { 
                	pB = headA;
            	}
            }
        }
        
        return pA;
    }
};

(5)方法五: 對于鏈表而言,我們最常用的方法還有一個雙指針的方法。

既然兩個鏈表尾巴部分一樣,那就兩個指針一起開始遍歷嘛,如果同時遍歷到同一個節(jié)點,那不就是我們要找的第一個公共節(jié)點嘛。

算法通關(guān)村第一關(guān)——鏈表經(jīng)典問題之第一個公共子節(jié)點筆記,算法,鏈表,筆記

但是要是像圖中這樣去遍歷,因為A和B長度不一樣,那pA和pB永遠(yuǎn)都不可能遍歷到同一個節(jié)點上嘛!

這個簡單啊,我們讓他們從同一起點出發(fā)不就好了,誰的跑道長,那我們就先讓誰先跑一點,保證兩個指針在同一起跑線就好啦!

算法通關(guān)村第一關(guān)——鏈表經(jīng)典問題之第一個公共子節(jié)點筆記,算法,鏈表,筆記文章來源地址http://www.zghlxwxcb.cn/news/detail-603242.html

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        // 遍歷A,得到A的長度
        ListNode *pA = headA;
        int lengthA = 0;
        while(pA != nullptr) {
            ++lengthA;
            pA = pA->next;
        }
        
        // 遍歷B,得到B的長度
        ListNode *pB = headB;
        int lengthB = 0;
        while(pB != nullptr) {
            ++lengthB;
            pB = pB->next;
        }
        
        pA = headA;
        pB = headB;
        
        // 計算長度差并統(tǒng)一起跑點
        if(lengthA - lengthB > 0) {
            int sub = lengthA - lengthB;
            while(sub != 0) {
                pA = pA->next;
                --sub;
            }
        } else if (lengthB - lengthA > 0) {
            int sub = lengthB - lengthA;
            while(sub != 0) {
                pB = pB->next;
                --sub;
            }
        }
        
        while(pA != nullptr && pB != nullptr) {
            if (pA == pB) {
                break;
            }
            
            pA = pA->next;
            pB = pB->next;
        }
        
        return pA;
    }
};

到了這里,關(guān)于算法通關(guān)村第一關(guān)——鏈表經(jīng)典問題之第一個公共子節(jié)點筆記的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 算法通關(guān)村第一關(guān)——鏈表經(jīng)典問題之雙指針筆記

    算法通關(guān)村第一關(guān)——鏈表經(jīng)典問題之雙指針筆記

    基本結(jié)構(gòu) 1.尋找中間結(jié)點 2.尋找倒數(shù)第k個元素 3.旋轉(zhuǎn)鏈表

    2024年02月14日
    瀏覽(21)
  • 算法通關(guān)村第一關(guān)——鏈表經(jīng)典問題之雙指針專題筆記

    我一直覺得雙指針是一個非常好用的方法,在鏈表中可以使用,在數(shù)組中依然可以,很靈活。 1. 尋找中間結(jié)點 ????????用兩個指針 slow 與 fast 一起遍歷鏈表。slow 一次走一步, fast 一次走兩步。那么當(dāng) fast 到達(dá)鏈表的末尾時,slow 必然位于中間。 2. 尋找倒數(shù)第K個元素 在這

    2024年02月15日
    瀏覽(24)
  • 《算法通關(guān)村第一關(guān)——鏈表青銅挑戰(zhàn)筆記》

    《算法通關(guān)村第一關(guān)——鏈表青銅挑戰(zhàn)筆記》

    鏈表中每個結(jié)點內(nèi)部的“生態(tài)環(huán)境”。 數(shù)據(jù)域存儲元素的值,指針域存放指針。 示例: c語言構(gòu)造鏈表 可分為三步 1.創(chuàng)建頭指針。 2.創(chuàng)建頭結(jié)點,使頭指針指向頭結(jié)點。 3.循環(huán)創(chuàng)建結(jié)點,并使前一個結(jié)點指向當(dāng)前結(jié)點。 1.)創(chuàng)建結(jié)點。 2.)使前一個結(jié)點指向當(dāng)前結(jié)點。 3.)

    2024年02月15日
    瀏覽(27)
  • 算法通關(guān)村第一關(guān)-鏈表青銅挑戰(zhàn)筆記

    算法通關(guān)村第一關(guān)-鏈表青銅挑戰(zhàn)筆記

    平時我們一般都是用數(shù)組,每個數(shù)組都會有一個相對應(yīng)的索引,這樣就使得數(shù)組能夠方便的調(diào)用出對應(yīng)索引得到需要的數(shù)據(jù),但是這也造成了一個問題,那就是不好在數(shù)組中插入或者刪除一個數(shù)據(jù),例如 int arr[]={1,2,4,5}如果我想在數(shù)組中的2和4中添加一個數(shù)據(jù)3 那么我們首先就

    2024年02月15日
    瀏覽(25)
  • 算法通關(guān)村第一關(guān)--鏈表青銅挑戰(zhàn)筆記

    算法通關(guān)村第一關(guān)--鏈表青銅挑戰(zhàn)筆記

    開始時間:2023年7月16日20:45:26 什么是鏈表,鏈表是一種通過指針串聯(lián)在一起的線性結(jié)構(gòu),每一個節(jié)點由兩部分組成,一個是數(shù)據(jù)域一個是指針域(存放指向下一個節(jié)點的指針),最后一個節(jié)點的指針域指向null(空指針的意思)。 鏈表的入口節(jié)點稱為鏈表的頭結(jié)點也就是hea

    2024年02月17日
    瀏覽(29)
  • 算法通關(guān)村第一關(guān) | 鏈表青銅挑戰(zhàn)筆記

    算法通關(guān)村第一關(guān) | 鏈表青銅挑戰(zhàn)筆記

    一、 什么是鏈表? 鏈表是一種比較簡單、很常見的數(shù)據(jù)結(jié)構(gòu),是一種物理存儲單元上非連續(xù)、非順序的存儲結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)的。 二、鏈表的特點 鏈表是一種比較簡單、很常見的數(shù)據(jù)結(jié)構(gòu),是線性表(List)的一種,是一種物理存

    2024年02月14日
    瀏覽(24)
  • 算法通關(guān)村第一關(guān)———鏈表青銅挑戰(zhàn)筆記

    算法通關(guān)村第一關(guān)———鏈表青銅挑戰(zhàn)筆記

    通過類來構(gòu)建節(jié)點,用next指針將節(jié)點連起來。 會有插入位置的范圍問題,不能超出鏈表范圍 會有刪除位置的范圍問題 構(gòu)造雙向鏈表 插入和刪除都有三種情況,頭中尾 ?

    2024年02月15日
    瀏覽(25)
  • 算法通關(guān)村第一關(guān)——鏈表青銅挑戰(zhàn)筆記

    算法通關(guān)村第一關(guān)——鏈表青銅挑戰(zhàn)筆記

    鏈表的基本單元就是 節(jié)點 ,也就是說鏈表是由一個一個節(jié)點構(gòu)成的。 而對于節(jié)點來說,里面至少會包含一個 指針 和一個 數(shù)據(jù)元素 ,也就是如下圖所示: 其中數(shù)據(jù)域用來存放數(shù)據(jù)元素,指針域用來存放指向下一個節(jié)點的指針,這樣一個一個連接起來的就是鏈表。如下圖所

    2024年02月16日
    瀏覽(27)
  • 編程導(dǎo)航算法通關(guān)村第一關(guān)|青銅|鏈表基礎(chǔ)

    編程導(dǎo)航算法通關(guān)村第一關(guān)|青銅|鏈表基礎(chǔ)

    JVM有棧區(qū)和堆區(qū) 棧區(qū):存引用,就是指向?qū)嶋H對象的地址。。 堆區(qū):存的是創(chuàng)建的對象。 定義 規(guī)范的鏈表定義 LeetCode算法題中常用 遍歷 插入 刪除 結(jié)點 結(jié)構(gòu)遍歷 插入 從頭插入 從尾插入 從某個值為key的節(jié)點后面插入 刪除 刪除頭結(jié)點 刪除尾結(jié)點 按值刪除

    2024年02月15日
    瀏覽(52)
  • 算法通關(guān)村第一關(guān)——鏈表青銅挑戰(zhàn)筆記(單鏈表)

    在LeeCode中一般這樣創(chuàng)建鏈表 要注意創(chuàng)建一個變量來遍歷,不要把head丟掉了 count position - 1可以方便操作,還能防止下標(biāo)越界(cur為null)

    2024年02月15日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包