劍指offer第二版-52.兩個(gè)鏈表的第一個(gè)公共節(jié)點(diǎn)

本系列導(dǎo)航:劍指offer(第二版)java實(shí)現(xiàn)導(dǎo)航帖

面試題52:兩個(gè)鏈表的第一個(gè)公共節(jié)點(diǎn)

題目要求:
輸入兩個(gè)單鏈表,找出它們的第一個(gè)公共節(jié)點(diǎn)。以下圖為例镜会,對(duì)一個(gè)公共節(jié)點(diǎn)為6所在的節(jié)點(diǎn)。

1 -> 2 -> 3 -> 6 -> 7
     4 -> 5 ↗

解題思路:

解法 思路 時(shí)間復(fù)雜度 空間復(fù)雜度
1 暴力求解 o(mn) o(1)
2 分別存入兩個(gè)棧,求棧中最深的相同節(jié)點(diǎn) o(m+n) o(m+n)
3 長(zhǎng)鏈表先行|n-m|步童社,轉(zhuǎn)化為等長(zhǎng)鏈表 o(m+n) o(1)

解法1:比較直接,不再贅述著隆。

解法2:從鏈表的尾部向前看扰楼,發(fā)現(xiàn)尾部是相同的,向前走會(huì)分叉美浦,找到分叉點(diǎn)即可弦赖。按照這個(gè)思路,如果這是雙向鏈表浦辨,即得到尾節(jié)點(diǎn)并能夠得到每個(gè)節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)蹬竖,那這個(gè)題就很簡(jiǎn)單了。對(duì)于單鏈表,本身是前節(jié)點(diǎn)->后節(jié)點(diǎn)币厕,想要得到后節(jié)點(diǎn)->前節(jié)點(diǎn)列另,可以借助于棧的后進(jìn)先出特性。兩個(gè)單鏈表分別入棧旦装,得到[1,2,3,6,7],[4,5,6,7]页衙,然后不斷出棧即可找到分叉點(diǎn)。

解法3:對(duì)于單鏈表阴绢,如果從頭結(jié)點(diǎn)開(kāi)始找公共節(jié)點(diǎn)店乐,一個(gè)麻煩點(diǎn)是兩個(gè)鏈表長(zhǎng)度可能不一致,因此兩個(gè)指針不同步(指兩個(gè)指針無(wú)法同時(shí)指向公共點(diǎn))呻袭。解決這個(gè)麻煩點(diǎn)响巢,整個(gè)問(wèn)題也就能順利解決。那么棒妨,能否讓兩個(gè)鏈表長(zhǎng)度一致踪古?長(zhǎng)鏈表先行幾步即可,因?yàn)殚L(zhǎng)鏈表頭部多出的那幾個(gè)節(jié)點(diǎn)一定不會(huì)是兩鏈表的公共節(jié)點(diǎn)券腔。以題目中的圖為例伏穆,可以讓1所在的鏈表先向前移動(dòng)1個(gè)節(jié)點(diǎn)到2,這樣就轉(zhuǎn)化為求下面這兩個(gè)鏈表的第一個(gè)公共節(jié)點(diǎn):

2 -> 3 -> 6 -> 7
4 -> 5 ↗

一個(gè)指針指向2纷纫,另一個(gè)指向4枕扫,然后同時(shí)遍歷,這應(yīng)該很容易了吧辱魁。需要對(duì)兩個(gè)鏈表先進(jìn)行一次遍歷求出長(zhǎng)度烟瞧,然后再同時(shí)遍歷求公共點(diǎn),時(shí)間復(fù)雜度o(n)染簇,空間復(fù)雜度o(1)参滴。

三種解法的代碼實(shí)現(xiàn)如下。

package chapter5;
import structure.ListNode;

import java.util.Stack;

/**
 * Created with IntelliJ IDEA
 * Author: ryder
 * Date  : 2017/8/15
 * Time  : 10:28
 * Description:兩個(gè)鏈表的第一個(gè)公共節(jié)點(diǎn)
 **/
public class P253_CommonNodesInLists {
    //思路一:暴力解決锻弓,時(shí)間復(fù)雜度o(mn)砾赔,空間復(fù)雜度o(1)
    //思路二:借助于兩個(gè)棧,時(shí)間復(fù)雜度o(m+n)青灼,空間復(fù)雜度o(m+n)
    //思路三:轉(zhuǎn)化為等長(zhǎng)鏈表暴心,時(shí)間復(fù)雜度o(m+n),空間復(fù)雜度o(1)
    public static ListNode<Integer> findFirstCommonNode(ListNode<Integer> head1,ListNode<Integer> head2){
        for(ListNode<Integer> node1=head1;node1!=null;node1=node1.next){
            for(ListNode<Integer> node2=head2;node2!=null;node2=node2.next){
                if(node1==node2)
                    return node1;
            }
        }
        return null;
    }
    public static ListNode<Integer> findFirstCommonNode2(ListNode<Integer> head1,ListNode<Integer> head2){
        Stack<ListNode<Integer>> stack1 = new Stack<>();
        Stack<ListNode<Integer>> stack2 = new Stack<>();
        for(ListNode<Integer> node1=head1;node1!=null;node1=node1.next)
            stack1.push(node1);
        for(ListNode<Integer> node2=head2;node2!=null;node2=node2.next)
            stack2.push(node2);
        ListNode<Integer> commonNode = null;
        while (!stack1.isEmpty() && !stack2.isEmpty()){
            if(stack1.peek()==stack2.peek()){
                commonNode = stack1.pop();
                stack2.pop();
            }
            else
                break;
        }
        return commonNode;
    }
    public static ListNode<Integer> findFirstCommonNode3(ListNode<Integer> head1,ListNode<Integer> head2){
        ListNode<Integer> node1 = head1,node2 = head2;
        int size1 = 0,size2 = 0;
        for (;node1!=null;node1 = node1.next)
            size1++;
        for (;node2!=null;node2 = node2.next)
            size2++;
        node1 = head1;
        node2 = head2;
        while (size1>size2){
            node1 = node1.next;
            size1--;
        }
        while (size2>size1){
            node2 = node2.next;
            size2--;
        }
        while (node1!=null){
            if(node1!=node2){
                node1 = node1.next;
                node2 = node2.next;
            }
            else
                break;
        }
        return node1;
    }
    public static void main(String[] args){
        // 1->2->3->6->7
        //    4->5↗
        ListNode<Integer> node1 = new ListNode<>(1);
        ListNode<Integer> node2 = new ListNode<>(2);
        ListNode<Integer> node3 = new ListNode<>(3);
        ListNode<Integer> node4 = new ListNode<>(4);
        ListNode<Integer> node5 = new ListNode<>(5);
        ListNode<Integer> node6 = new ListNode<>(6);
        ListNode<Integer> node7 = new ListNode<>(7);
        node1.next = node2;
        node2.next = node3;
        node3.next = node6;
        node4.next = node5;
        node5.next = node6;
        node6.next = node7;
        ListNode<Integer> commonNode = findFirstCommonNode(node1,node4);
        System.out.println(commonNode.val);
        ListNode<Integer> commonNode2 = findFirstCommonNode2(node1,node4);
        System.out.println(commonNode2.val);
        ListNode<Integer> commonNode3 = findFirstCommonNode2(node1,node4);
        System.out.println(commonNode3.val);
    }
}

運(yùn)行結(jié)果

6
6
6
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末杂拨,一起剝皮案震驚了整個(gè)濱河市专普,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌弹沽,老刑警劉巖檀夹,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筋粗,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡击胜,警方通過(guò)查閱死者的電腦和手機(jī)亏狰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門役纹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)偶摔,“玉大人,你說(shuō)我怎么就攤上這事促脉〕秸” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵瘸味,是天一觀的道長(zhǎng)宫仗。 經(jīng)常有香客問(wèn)我,道長(zhǎng)旁仿,這世上最難降的妖魔是什么藕夫? 我笑而不...
    開(kāi)封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮枯冈,結(jié)果婚禮上毅贮,老公的妹妹穿的比我還像新娘。我一直安慰自己尘奏,他們只是感情好滩褥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著炫加,像睡著了一般瑰煎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上俗孝,一...
    開(kāi)封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天酒甸,我揣著相機(jī)與錄音,去河邊找鬼赋铝。 笑死烘挫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的柬甥。 我是一名探鬼主播饮六,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼苛蒲!你這毒婦竟也來(lái)了卤橄?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤臂外,失蹤者是張志新(化名)和其女友劉穎窟扑,沒(méi)想到半個(gè)月后喇颁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嚎货,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年橘霎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殖属。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡姐叁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出洗显,到底是詐尸還是另有隱情外潜,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布挠唆,位于F島的核電站处窥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏玄组。R本人自食惡果不足惜滔驾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望俄讹。 院中可真熱鬧哆致,春花似錦、人聲如沸颅悉。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)剩瓶。三九已至驹溃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間延曙,已是汗流浹背豌鹤。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枝缔,地道東北人布疙。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像愿卸,于是被迫代替她去往敵國(guó)和親灵临。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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