二叉樹-最低公共父節(jié)點(2)

在上一篇文章中我們用的是暴力的遍歷判斷的方法,然而在樹有關(guān)的題目中罪裹,保存路徑也是一個很常用的思路饱普,比如求兩個節(jié)點的最短路徑,求路徑長度状共。
并且為了改善算法的復雜度套耕,我們可以嘗試減少遍歷的次數(shù),上一種方法中峡继,我們遍歷了兩次冯袍,這次,我們試著保存遍歷的路徑碾牌,然后求兩個路徑的公共節(jié)點康愤。
首先我們有一個getNodePath 函數(shù),該函數(shù)會將從頭結(jié)點到給定節(jié)點的路徑保存舶吗,然后有一個lastCommonNode函數(shù)求路徑的公共節(jié)點征冷。

首先我們看這個函數(shù),這個函數(shù)的設計的思路值得我學習誓琼。

  • 返回量:該函數(shù)返回的是布爾型變量检激,表示該節(jié)點是否在包含指定node的路徑上。
    為什么要如此選取呢腹侣?為什么不直接返回一個list的指針叔收?我們要通過這個函數(shù)得到list,為什么要作為一個參數(shù)傳進去而不是作為返回量傲隶?
    我們看函數(shù)的結(jié)構(gòu)饺律,和大多數(shù)遍歷樹的函數(shù)一樣,該函數(shù)也是遞歸的伦籍。我們的參數(shù)之一是樹的根節(jié)點蓝晒,意思是從這個節(jié)點往下遍歷。
    整個函數(shù)有四個分支帖鸦,分別是
    1芝薇,該根節(jié)點就是要找的節(jié)點,返回true
    2作儿,否則在左子樹尋找
    3洛二,否則在右子樹尋找
    4,要找的節(jié)點不在當前根節(jié)點的下面攻锰。此時刪除掉路徑中存儲的當前節(jié)點晾嘶。
    由此,我們遍歷整個樹之后留下 的節(jié)點就是路徑
bool getNodePath(node* ptree, node* pnode,std::list<node*>& path)
{
    if (ptree == pnode)
        return true;

    path.push_back(ptree);
    //在遞歸中娶吞,我們只關(guān)心這一輪要處理的節(jié)點垒迂,因此只需要把ptree放進去而不需要在left和right中加入push_back

    bool found = false;
    if (ptree->lnode)
    {
        found = getNodePath(ptree->lnode, pnode, path);
    }
    if (!found&&ptree->rnode)
    {
        found = getNodePath(ptree->rnode, pnode, path);
    }
    if (!found)
        path.pop_back();
    return found;
}

由于我對遞歸函數(shù)還是不太熟悉,在設想的時候總是會在左右子樹分支的函數(shù)里面加上path.push_back(tree->left) 妒蛇,總是覺得處理當前節(jié)點就要有顯式的語句机断,但是實際上后面的遞歸調(diào)用會把這個節(jié)點加進去的,如果還寫绣夺,那就是重復了吏奸。
在遞歸的函數(shù)中我們應該這樣想,我們只處理當前節(jié)點陶耍,當前節(jié)點的子節(jié)點留給遞歸就行了奋蔚。

下面是完整的函數(shù):

//way2,get the path , the get the last common node of two paths
#include <list>

bool getNodePath(node* ptree, node* pnode,std::list<node*>& path)
{
    if (ptree == pnode)
        return true;

    path.push_back(ptree);
    //在遞歸中,我們只關(guān)心這一輪要處理的節(jié)點烈钞,因此只需要把ptree放進去而不需要在left和right中加入push_back

    bool found = false;
    if (ptree->lnode)
    {
        found = getNodePath(ptree->lnode, pnode, path);
    }
    if (!found&&ptree->rnode)
    {
        found = getNodePath(ptree->rnode, pnode, path);
    }
    if (!found)
        path.pop_back();
    return found;
}
node* lastCommonNode_l(std::list<node*>& path1, std::list<node*>& path2)
{
    node* path = NULL;
    std::list<node*>::const_iterator ptr1=path1.begin();
    std::list<node*>::const_iterator ptr2 = path2.begin();
    while (ptr1 != path1.end() && ptr2 != path2.end())
    {
        if (*ptr1 == *ptr2)
            path = *ptr1;//why *ptr
            //we do not return here since we need the last common node 
        ptr1++;
        ptr2++;
    }
    return path;//attention
    
}
node* LastCommonNode(node* tree, node* node1, node* node2)
{
    if (tree == NULL || !node1 || node2)
        return;

    std::list<node*> path1;
    std::list<node*> path2;
    getNodePath(tree, node1, path1);
    getNodePath(tree, node1, path2);

    return lastCommonNode_l(path1, path2);
}

文章參考何海濤大神文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泊碑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子毯欣,更是在濱河造成了極大的恐慌蛾狗,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仪媒,死亡現(xiàn)場離奇詭異沉桌,居然都是意外死亡,警方通過查閱死者的電腦和手機算吩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門留凭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人偎巢,你說我怎么就攤上這事蔼夜。” “怎么了压昼?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵求冷,是天一觀的道長瘤运。 經(jīng)常有香客問我,道長匠题,這世上最難降的妖魔是什么拯坟? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮韭山,結(jié)果婚禮上郁季,老公的妹妹穿的比我還像新娘。我一直安慰自己钱磅,他們只是感情好梦裂,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盖淡,像睡著了一般年柠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上褪迟,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天彪杉,我揣著相機與錄音,去河邊找鬼牵咙。 笑死派近,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的洁桌。 我是一名探鬼主播渴丸,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼另凌!你這毒婦竟也來了谱轨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤吠谢,失蹤者是張志新(化名)和其女友劉穎土童,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體工坊,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡献汗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了王污。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罢吃。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖昭齐,靈堂內(nèi)的尸體忽然破棺而出尿招,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布就谜,位于F島的核電站怪蔑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏丧荐。R本人自食惡果不足惜缆瓣,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望篮奄。 院中可真熱鬧捆愁,春花似錦割去、人聲如沸窟却。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夸赫。三九已至,卻和暖如春咖城,著一層夾襖步出監(jiān)牢的瞬間茬腿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工宜雀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留切平,地道東北人。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓辐董,卻偏偏與公主長得像悴品,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子简烘,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

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

  • 參考兩篇其他bolg總結(jié)的二叉樹:https://github.com/xy7313/lintcode/blob/...
    暗黑破壞球嘿哈閱讀 2,376評論 0 1
  • 樹的概述 樹是一種非常常用的數(shù)據(jù)結(jié)構(gòu)苔严,樹與前面介紹的線性表,棧孤澎,隊列等線性結(jié)構(gòu)不同届氢,樹是一種非線性結(jié)構(gòu) 1.樹的定...
    Jack921閱讀 4,462評論 1 31
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)覆旭,斷路器退子,智...
    卡卡羅2017閱讀 134,699評論 18 139
  • 1 序 2016年6月25日夜,帝都型将,天下著大雨絮供,拖著行李箱和同學在校門口照了最后一張合照,搬離寢室打車去了提前租...
    RichardJieChen閱讀 5,108評論 0 12
  • 《踏春廣陽島》 日麗天清幸廣陽茶敏,一灣半島菜花黃壤靶。 大江水暖聽風急,沃野蜂吟聞蜜香惊搏。 綽約田間淑女舞贮乳,...
    龍鳳來閱讀 893評論 0 2