一題一算法2018-02-06(重建二叉樹)

題目:重建二叉樹


題目描述:

輸入某二叉樹的前序遍歷和中序遍歷的結(jié)果,請重建出該二叉樹。假設(shè)輸入的前序遍歷和中序遍歷的結(jié)果中都不含重復的數(shù)字馆里。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6}染坯,則重建二叉樹并返回。


題目知識:

首先看題目應該最先看到的是這個幾個關(guān)鍵點:1揽碘、二叉樹,2园匹、二叉樹的前中后三種遍歷雳刺。
先序遍歷:遍歷規(guī)則 根-左-右
中序遍歷:遍歷規(guī)則 左-根-右
后序遍歷:遍歷規(guī)則 左-右-根

image.png

接下來的排序:
先序遍歷:ABCDEFGHK
中序遍歷:BDCAEHGKF
后序遍歷:DCBHKGFEA
先說中序遍歷,先序遍歷的規(guī)則是左根右
此時A是根節(jié)點裸违,遍歷A的左子樹掖桦;
A的左子樹存在,找到B供汛,此時B看做根節(jié)點枪汪,遍歷B的左子樹;
B的左子樹不存在怔昨,返回B雀久,根據(jù)【左根右】的遍歷規(guī)則,記錄B趁舀,遍歷B的右子樹赖捌;
B的右子樹存在,找到C赫编,此時C看做根節(jié)點巡蘸,遍歷C的左子樹;
C的左子樹存在擂送,找到D悦荒,由于D是葉子節(jié)點,無左子樹嘹吨,記錄D搬味,無右子樹,返回C蟀拷,根據(jù)【左根右】的遍歷規(guī)則碰纬,記錄C,遍歷C的右子樹问芬;
C的右子樹不存在悦析,返回B,B的右子樹遍歷完此衅,返回A强戴;
至此亭螟,A的左子樹遍歷完畢,根據(jù)【左根右】的遍歷規(guī)則骑歹,記錄A预烙,遍歷A的右子樹;
A的右子樹存在道媚,找到E扁掸,此時E看做根節(jié)點,遍歷E的左子樹最域;
E的左子樹不存在谴分,返回E,根據(jù)【左根右】的遍歷規(guī)則羡宙,記錄E狸剃,遍歷E的右子樹;
E的右子樹存在狗热,找到F,此時F看做根節(jié)點虑省,遍歷F的左子樹匿刮;
F的左子樹存在,找到G探颈,此時G看做根節(jié)點熟丸,遍歷G的左子樹;
G的左子樹存在伪节,找到H光羞,由于H是葉子節(jié)點,無左子樹怀大,記錄H纱兑,無右子樹,返回G化借,根據(jù)【左根右】的遍歷規(guī)則潜慎,記錄G,遍歷G的右子樹蓖康;
G的右子樹存在铐炫,找到K,由于K是葉子節(jié)點蒜焊,無左子樹倒信,記錄K,無右子樹泳梆,返回G鳖悠,根據(jù)【左根右】的遍歷規(guī)則榜掌,記錄F,遍歷F的右子樹竞穷;
F的右子樹不存在唐责,返回F,E的右子樹遍歷完畢瘾带,返回A鼠哥;
至此,A的右子樹也遍歷完畢看政;
那么接下來的前序和后序遍歷類似的方式遍歷朴恳。

題目分析

已知當知道先序中序遍歷的序列,或者知道中序后序遍歷序列時我們可以唯一確定一個二叉樹允蚣,當只知道先序后序的時候我們不能確定唯一的一棵樹于颖。
那我們先聯(lián)系這樣一個題目:
已知先序序列:ABCDEFGH,中序序列:BDCEAFHG,求出最終的序列來。
首先嚷兔,先序和中序的遍歷規(guī)則分別是根左右左根右,那么我們可以知道此序列的根節(jié)點是A森渐,在中序序列中,BDCE是A的左子樹冒晰,F(xiàn)HG是A的右子樹同衣。

image.png

于是先序遍歷也就分成這樣的
image.png

而B又在先序遍歷中是A左子樹的根節(jié)點,再回到中序遍歷中B是A座子樹的根節(jié)點壶运,那么DCE就是B的右子樹耐齐,那么此時的圖就變成了
image.png

那么我們接下來在看CDE,看先序遍歷知道CCDE的根節(jié)點蒋情,再根據(jù)中序遍歷DCE知道D是C的左葉子節(jié)點埠况,E是C的有葉子節(jié)點,那么此時我們的整個左子樹完成了棵癣。
image.png

我們同樣對右子樹進行操作辕翰,在先序中右子樹的順序是:FGH,那么此右子樹的根節(jié)點是F浙巫,再看中序的順序是:FHG金蜀,F(xiàn)是根節(jié)點,那HG是F的右子樹

image.png

再看先序遍歷發(fā)現(xiàn)接下來的根節(jié)點是G的畴,那么F的右子樹節(jié)點是G渊抄,再看中序遍歷的結(jié)果HG,H是G的左子樹丧裁。
image.png

接下來
我們知道中序遍歷:CEDFBAHG护桦,后序遍歷:EFDCBHGA
我們知道:
1、根據(jù)后序遍歷知道此二叉樹的根節(jié)點是A煎娇,那么在中序遍歷中我們就可以分成左子樹:CEDFB二庵,右子樹HG贪染。
2、先看左子樹的后序:EFDCB催享,我們知道左子樹的根節(jié)點是B杭隙,再到中序CEDFB中我們知道。CEDF是B的左子樹因妙。
3痰憎、后序:EFDC,知道B的左子樹的根節(jié)點是C攀涵,铣耘,而在中序CEDF中我們知道EDF是C的右子樹
4、后序:EFD以故,知道C的右子樹的根節(jié)點是D蜗细,而在中序EDF中我們知道E和F分別是D的左葉子節(jié)點和有葉子結(jié)點
5、中序:HG怒详,我們知道是A的右子樹炉媒,后序中HGA,說明A的右子樹的根節(jié)點是G昆烁。
6橱野、中序遍歷中是HG,說明H是G的左葉子節(jié)點

image.png

綜上所述善玫,我們可以知道從遍歷中獲取整個二叉樹的方法

題目代碼:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        if(pre.size() != vin.size()||pre.size() == 0 || vin.size() == 0) return NULL;
        else{
            TreeNode* resNode = createTreeNodeHelper(pre,vin,0,0,vin.size()-1);
            return resNode;
        }
    }
    TreeNode* createTreeNodeHelper(vector<int> pre, vector<int> vin,int preRootPos,int vinLeft,int vinRight){
        // pre 前序 vin 中序 preRootPos 前序根節(jié)點位置 vinLeft 中序左邊界 vinRight 中序右邊界
        int vinRootPos,rootVal;
        rootVal = pre[preRootPos];//前序遍歷中根節(jié)點位置的值
        if(vinLeft>vinRight) return NULL;
        for(int i = vinLeft; i<=vinRight;i++){
            if(vin[i] == rootVal)
                vinRootPos = i; //根據(jù)根節(jié)點找到中序中根節(jié)點的位置vinRootPos,
        }
        int leftLen = vinRootPos - vinLeft;
        
        TreeNode* resRoot = new TreeNode(rootVal);
        resRoot->left = createTreeNodeHelper(pre,vin,preRootPos+1,vinLeft,vinRootPos-1);
        resRoot->right = createTreeNodeHelper(pre,vin,preRootPos+leftLen+1,vinRootPos + 1, vinRight);
        return resRoot;
    }
};

通過迭代的方式,不斷查找密强。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茅郎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子或渤,更是在濱河造成了極大的恐慌系冗,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件薪鹦,死亡現(xiàn)場離奇詭異掌敬,居然都是意外死亡,警方通過查閱死者的電腦和手機池磁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門奔害,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人地熄,你說我怎么就攤上這事华临。” “怎么了端考?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵雅潭,是天一觀的道長揭厚。 經(jīng)常有香客問我,道長扶供,這世上最難降的妖魔是什么筛圆? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮椿浓,結(jié)果婚禮上太援,老公的妹妹穿的比我還像新娘。我一直安慰自己轰绵,他們只是感情好粉寞,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著左腔,像睡著了一般唧垦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上液样,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天振亮,我揣著相機與錄音,去河邊找鬼鞭莽。 笑死坊秸,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的澎怒。 我是一名探鬼主播褒搔,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼喷面!你這毒婦竟也來了星瘾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤惧辈,失蹤者是張志新(化名)和其女友劉穎琳状,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盒齿,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡念逞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了边翁。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翎承。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖倒彰,靈堂內(nèi)的尸體忽然破棺而出审洞,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布芒澜,位于F島的核電站仰剿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏痴晦。R本人自食惡果不足惜南吮,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望誊酌。 院中可真熱鬧部凑,春花似錦、人聲如沸碧浊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽箱锐。三九已至比勉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間驹止,已是汗流浹背浩聋。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留臊恋,地道東北人衣洁。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像抖仅,于是被迫代替她去往敵國和親坊夫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

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

  • 樹的概述 樹是一種非常常用的數(shù)據(jù)結(jié)構(gòu)撤卢,樹與前面介紹的線性表践樱,棧,隊列等線性結(jié)構(gòu)不同凸丸,樹是一種非線性結(jié)構(gòu) 1.樹的定...
    Jack921閱讀 4,455評論 1 31
  • 這幾天開學,學校還在上課袱院,最近也是在找工作屎慢,很多天都沒有更新文章,現(xiàn)在補一篇二叉樹的文章忽洛。 最近校招公司的筆試陸續(xù)...
    zero_sr閱讀 3,959評論 0 5
  • 數(shù)據(jù)結(jié)構(gòu)和算法--二叉樹的實現(xiàn) 幾種二叉樹 1腻惠、二叉樹 和普通的樹相比,二叉樹有如下特點: 每個結(jié)點最多只有兩棵子...
    sunhaiyu閱讀 6,464評論 0 14
  • 給定一個前序和中序變量的結(jié)果欲虚,寫一個算法重建這棵樹:前序: a b d c e f中序: d b a e c f...
    HangChen閱讀 538評論 0 3
  • 本文轉(zhuǎn)自 http://www.cnblogs.com/manji/p/4903990.html二叉樹-****你...
    doublej_yjj閱讀 681評論 0 8