兩個鏈表中的第一個公共節(jié)點(diǎn)(java)

題目描述:

輸入兩個鏈表缸匪,找出它們的第一個公共結(jié)點(diǎn)。

分析:

思路一:暴力解法准夷,強(qiáng)烈不建議!
遍歷第一個鏈表的每個節(jié)點(diǎn)莺掠,同時每次都遍歷一遍另一個鏈表衫嵌,看是否有節(jié)點(diǎn)和這個節(jié)點(diǎn)相同,如果有相同節(jié)點(diǎn)就是公共節(jié)點(diǎn)彻秆,如果沒有楔绞,就繼續(xù)向下遍歷结闸。


思路二:長鏈表先走,再同步遍歷
兩個鏈表比較長短酒朵,計(jì)算出兩者的長度差x桦锄,比較長的鏈表先往前走x步,然后長短鏈表一起同步向前走蔫耽,看遍歷到的節(jié)點(diǎn)是否相同结耀,如果相同就是第一個公共節(jié)點(diǎn)。


思路三:用hashMap數(shù)據(jù)結(jié)構(gòu)
第一個while循環(huán)遍歷第一個鏈表匙铡,將其所有節(jié)點(diǎn)放入hashmap中
第二個while遍歷第二個鏈表图甜,用containsKey判斷這個節(jié)點(diǎn)值是否存在第一個鏈表中。
(這種思路基本上就是用空間換時間)


思路四:兩個鏈表的公共節(jié)點(diǎn)一定在鏈表的尾部
若連個鏈表存在公共節(jié)點(diǎn)鳖眼,則它們的尾部一定從第一個公共節(jié)點(diǎn)開始完全相同黑毅。

我們分析有公共結(jié)點(diǎn)的兩個鏈表有哪些特點(diǎn)。從鏈表結(jié)點(diǎn)的定義可以看出钦讳,這兩個鏈表是單鏈表矿瘦。如果兩個單向鏈表有公共的結(jié)點(diǎn),那么這兩個鏈表從某一結(jié)點(diǎn)開始愿卒,它們的next都指向同一個結(jié)點(diǎn)缚去,但由于是單向鏈表的結(jié)點(diǎn),之后他們所有結(jié)點(diǎn)都是重合的掘猿,不可能再出現(xiàn)分叉病游。所以兩個有公共結(jié)點(diǎn)而部分重合的鏈表,拓?fù)湫螤铋_起來像一個Y稠通,而不可能像X衬衬。

兩個鏈表的公共節(jié)點(diǎn)圖解

設(shè) A 的長度為 a + c,B 的長度為 b + c改橘,其中 c 為尾部公共部分長度滋尉,可知 a + c + b = b + c + a。
當(dāng)訪問 A 鏈表的指針訪問到鏈表尾部時飞主,令它從鏈表 B 的頭部重新開始訪問鏈表 B狮惜;同樣地,當(dāng)訪問 B 鏈表的指針訪問到鏈表尾部時碌识,令它從鏈表 A 的頭部重新開始訪問鏈表 A碾篡。這樣就能控制訪問 A 和 B 兩個鏈表的指針能同時訪問到交點(diǎn)。

解答:

思路二:長鏈表先走n步筏餐,然后長短鏈表共同向前遍歷

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
 if (pHead1 == null || pHead2 == null) return null;
        if (pHead1 == pHead2) return pHead1;
        int len1 = getLength(pHead1);
        int len2 = getLength(pHead2);
        //讓比較長的鏈表先走幾步
        if (len1 > len2) {
            for (int i = 0; i < (len1 - len2); i++) {
                pHead1 = pHead1.next;
            }
        } else {
            for (int i = 0; i < (len2 - len1); i++) {
                pHead2 = pHead2.next;
            }
        }
        boolean flag = false;  //標(biāo)志位开泽,判斷是否走到第一個公共節(jié)點(diǎn)
        ListNode result = null;
        while (!flag) {
            if (pHead1 == null || pHead2 == null) {
                return null;
            }
            if (pHead1.val == pHead2.val) {
                flag = true;
                result = pHead1;
            } else {
                pHead1 = pHead1.next;
                pHead2 = pHead2.next;
            }
        }
        return result;
    }

    /*求鏈表長度的方法,每次求鏈表漲肚魁瞪,需要遍歷一次單鏈表*/
    public static int getLength(ListNode pHead) {
        int len = 1;
        ListNode current = pHead;
        while (current.next != null) {
            len++;
            current = current.next;
        }
        return len;
    }
}
運(yùn)行成功

這種方法可行穆律,但是求鏈表的長度需要遍歷一次鏈表惠呼,然后找到公共節(jié)點(diǎn)又要遍歷兩個鏈表,時間復(fù)雜度是O(M+N),但是鑒于每個鏈表都要遍歷兩遍峦耘,所以耗時還是比較多的剔蹋。

如果想耗時比較少,可以考慮用空間換取時間辅髓,用hashmap存儲鏈表1中的節(jié)點(diǎn)值泣崩,然后遍歷一遍鏈表2即可。從hashmap中查找某個key值是否存在耗費(fèi)的時間為O(1)利朵。


思路四:當(dāng)指針1訪問到A的末尾開始訪問B律想,當(dāng)指針2訪問到B的末尾開始訪問A,這樣绍弟,指針1,2會同時訪問到公共節(jié)點(diǎn)技即。

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
   public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        ListNode l1 = pHead1, l2 = pHead2;
        while (l1 != l2) {
            l1 = (l1 == null) ? pHead2 : l1.next;
            l2 = (l2 == null) ? pHead1 : l2.next;
        }
        return l1;
    }
}
運(yùn)行成功

簡潔高效的代碼是程序媛永恒的追求!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末樟遣,一起剝皮案震驚了整個濱河市而叼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌豹悬,老刑警劉巖葵陵,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瞻佛,居然都是意外死亡脱篙,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門伤柄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绊困,“玉大人,你說我怎么就攤上這事适刀〕永剩” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵笔喉,是天一觀的道長取视。 經(jīng)常有香客問我,道長常挚,這世上最難降的妖魔是什么作谭? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮奄毡,結(jié)果婚禮上折欠,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好怨酝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著那先,像睡著了一般农猬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上售淡,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天斤葱,我揣著相機(jī)與錄音,去河邊找鬼揖闸。 笑死揍堕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的汤纸。 我是一名探鬼主播衩茸,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼贮泞!你這毒婦竟也來了楞慈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤啃擦,失蹤者是張志新(化名)和其女友劉穎囊蓝,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體令蛉,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡聚霜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了珠叔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝎宇。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖运杭,靈堂內(nèi)的尸體忽然破棺而出夫啊,到底是詐尸還是另有隱情,我是刑警寧澤辆憔,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布撇眯,位于F島的核電站,受9級特大地震影響虱咧,放射性物質(zhì)發(fā)生泄漏熊榛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一腕巡、第九天 我趴在偏房一處隱蔽的房頂上張望玄坦。 院中可真熱鬧,春花似錦、人聲如沸煎楣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽择懂。三九已至喻喳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間困曙,已是汗流浹背表伦。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慷丽,地道東北人蹦哼。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像要糊,于是被迫代替她去往敵國和親纲熏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354

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

  • “不如我們重頭來過”杨耙。 黎耀輝說赤套,分開之后,他最怕聽到何寶榮那句老話珊膜。何止黎耀輝容握,這世間,你你我我车柠,皆抵不過這一句...
    陶影閱讀 1,150評論 3 9
  • 時間太短 日子太長 我曾帶著理想和慌張 在你渺遠(yuǎn)不及的身旁 我也常在碌碌無為里謬想 如果你也在我所不及的遠(yuǎn)方 我要...
    海紅豆的奇幻漂流之旅閱讀 291評論 1 1
  • 好久沒有寫文字了,已經(jīng)忘記如何開場了塑陵,時不時會想起學(xué)生時代感憾,懷念那些一點(diǎn)點(diǎn)埋葬夢想的日子。有時候很想回到那個做夢的...
    lowett閱讀 411評論 0 0
  • 你笑容細(xì)致地隱藏于手 被不安和霧穿透 你坐在鏡子里面 燕子徘徊指間 細(xì)細(xì)的疼痛一點(diǎn)一點(diǎn) 印染一切 2014.10.25
    楊戲水閱讀 207評論 2 1
  • 1.有著不上不小的年紀(jì)卻沒有一個想要拔高的心 別說這個世界不公平令花,老給自己放縱的借口和理由阻桅,安于現(xiàn)狀的過著眼前的生...
    蹲在墻角等月亮閱讀 396評論 0 0