程序員面試經(jīng)典chapter4 Trees and Graphs

第一題 二叉樹(shù)平衡檢查

題目描述: 檢查二叉樹(shù)是否平衡鸟废,對(duì)于任意一個(gè)節(jié)點(diǎn)來(lái)說(shuō)兩個(gè)子樹(shù)的高度差小于1
題目給出的函數(shù)為

class Balance {
public:
    bool isBalance(TreeNode* root) {
        // write code here
    }
};

遍歷方式應(yīng)該用后序(post-order)先左邊再右邊最后到根偶翅,所以當(dāng)判斷根節(jié)點(diǎn)是否平衡的時(shí)候就判斷下一個(gè)depth節(jié)點(diǎn)是否平衡,以此類推朱监。用遞歸的的方式來(lái)判斷平衡庵楷,不要多次計(jì)算子節(jié)點(diǎn)踪央,子樹(shù)的高度。主要函數(shù)以遞歸的形式求深一層的節(jié)點(diǎn)平衡渊额,一個(gè)utility函數(shù)用來(lái)返回求得的當(dāng)前節(jié)點(diǎn)的深度况木,所以最后通過(guò)代碼為:


/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/

class Balance {
public:
    bool isBalance(TreeNode* root) {
        if(root == NULL)
            return true;
        // write code here
        if((depth(root->left)-depth(root->right)>1) || (depth(root->left)-depth(root->right)<-1))
           return false;
        else
            return isBalance(root->left)&&isBalance(root->right);
    }
     
    int depth(TreeNode* root){
        if(root == NULL)
            return 0;
        return depth(root->left)>depth(root->right)? depth(root->left)+1:depth(root->right)+1;
    }
};

第二題 有向路徑檢查

題目描述:檢查一個(gè)有向圖中兩個(gè)節(jié)點(diǎn)之間是否有 有向路徑
題目給出的結(jié)構(gòu)體為:

struct UndirectedGraphNode {
    int label;
    vector<struct UndirectedGraphNode *> neighbors;
    UndirectedGraphNode(int x) : label(x) {}
};

單純的想象垒拢,肯定還是遍歷了,至于說(shuō)是深度優(yōu)先還是廣度優(yōu)先火惊,我一開(kāi)始也不知道求类,憑直覺(jué)來(lái)做,很簡(jiǎn)單屹耐。

從節(jié)點(diǎn)a指向節(jié)點(diǎn)b(a->b)尸疆,建立一個(gè)循環(huán)知會(huì)每一個(gè)a的neighbour,首先判斷a的neighbour是否是b惶岭。


queue<UndirectedGraphNode*> que;
        map<UndirectedGraphNode*,bool> map1;
        //que.push(a);
        while(!que.empty()){
            //UndirectedGraphNode* ptr=que.front();
            map1[ptr]=true;
            for(int i=0;i<ptr->neighbors.size();i++)
            {
                if((ptr->neighbors)[i]==b){...}
            }

如果隔壁鄰居正好是b寿弱,你猜怎樣,那就是有向咯按灶,那如果不是症革,就要從隔壁鄰居的隔壁鄰居開(kāi)始找,所以我需要一個(gè)可以先進(jìn)先出的結(jié)構(gòu)鸯旁,隊(duì)列噪矛。
也就是說(shuō)在循環(huán)a的隔壁鄰居之后(a->neighbour),再?gòu)膭偛诺牡谝粋€(gè)隔壁鄰居開(kāi)始繼續(xù)尋找a隔壁的隔壁的鄰居...以此類推铺罢。


while(!que.empty()){
           UndirectedGraphNode* ptr=que.front();
            map1[ptr]=true;
            for(int i=0;i<ptr->neighbors.size();i++)
            {
                if((ptr->neighbors)[i]==b)
                    return true;
                if(ptr->neighbors[i]&&map1[ptr->neighbors[i]]!=true)
                    que.push((ptr->neighbors)[i]);
            }
            que.pop();
        }

回到最開(kāi)始的問(wèn)題艇挨,這就應(yīng)該是廣度優(yōu)先遍歷了圖,因?yàn)椴](méi)有從單個(gè)的neighbour開(kāi)始立即尋找該neighbour的下一個(gè)節(jié)點(diǎn)韭赘,而是在建立的循環(huán)中每次首先遍歷周圍所有的neighbour缩滨。
下面是完整代碼:


/*
struct UndirectedGraphNode {
    int label;
    vector<struct UndirectedGraphNode *> neighbors;
    UndirectedGraphNode(int x) : label(x) {}
};*/

class Path {
public:
    bool checkPath(UndirectedGraphNode* a, UndirectedGraphNode* b) {
        // write code here
        return check(a,b)||check(b,a);
    }
    bool check(UndirectedGraphNode* a, UndirectedGraphNode* b){
        if(a==NULL||b==NULL)
            return false;
        if(a==b)
            return true;
        queue<UndirectedGraphNode*> que;
        map<UndirectedGraphNode*,bool> map1;
        que.push(a);
        while(!que.empty()){
           UndirectedGraphNode* ptr=que.front();
            map1[ptr]=true;
            for(int i=0;i<ptr->neighbors.size();i++)
            {
                if((ptr->neighbors)[i]==b)
                    return true;
                if(ptr->neighbors[i]&&map1[ptr->neighbors[i]]!=true)
                    que.push((ptr->neighbors)[i]);
            }
            que.pop();
        }
        return false;
    }
};

第三題 實(shí)現(xiàn)一個(gè)最小BST

題目描述:給定一個(gè)array,其中元素按照大小排列辞居,創(chuàng)建一個(gè)高度最小的二叉查找樹(shù)楷怒。
首先回顧一下什么是BST好了:

  • 非子葉節(jié)點(diǎn)都只有兩個(gè)子節(jié)點(diǎn)蛋勺,分別是左兒子和右兒子
  • 而每個(gè)非子葉節(jié)點(diǎn)的左兒子小于該非子葉節(jié)點(diǎn)瓦灶,該非子葉節(jié)點(diǎn)又比右兒子小

因?yàn)橐呀?jīng)既定了一個(gè)從小到大排列的數(shù)組,那就從中間開(kāi)始作為該二叉樹(shù)的根節(jié)點(diǎn)抱完,每次insert左兒子(←)和右兒子(→)的時(shí)候就正好將前半段與后半段相應(yīng)的繼續(xù)遞歸添加贼陶。
其實(shí)...好像并沒(méi)有最小這一說(shuō),總之通過(guò)代碼很簡(jiǎn)單巧娱,在這里:


class MinimalBST {
public:
    int buildMinimalBST(vector<int> vals) {
        // write code here
        int height=0;
        addToTree(vals, 0, vals.size() - 1, height);
        return height;
    }
    TreeNode *addToTree(vector<int> vals,int start,int end,int& n){
        if(end<start){
            n=0;
            return NULL;
        }
        int mid = start + (end - start) / 2;
        TreeNode *midroot = new TreeNode(vals[mid]);//根節(jié)點(diǎn)
        int left, right;//左右子樹(shù)
        midroot->left = addToTree(vals, start, mid - 1, left);//左子樹(shù)
        midroot->right = addToTree(vals, mid + 1, end, right);//右子樹(shù)
        n = (left >= right ? left : right) + 1;//計(jì)算當(dāng)前高度
        return midroot;
    }
};

第四題 檢查是否為BST

題目描述:實(shí)現(xiàn)一個(gè)函數(shù)檢查一個(gè)給定二叉樹(shù)是否為查找二叉樹(shù)
題目給定結(jié)構(gòu)體:


struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};

好吧碉怔,重復(fù)了剛才回顧的BST的定義,就一個(gè)非子葉節(jié)點(diǎn)來(lái)說(shuō)滿足兩條:1. 左兒子和右兒子禁添;2.左兒子比該節(jié)點(diǎn)小撮胧,右兒子比該節(jié)點(diǎn)大

root->left->val < root->val
root->right->val > root->val

所以最終通過(guò)代碼為:


/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/

class Checker {
public:
    bool checkBST(TreeNode* root) {
        // write code here
        if(root==NULL)
            return true;
         
        if(root->left!=NULL){
            if(root->left->val>root->val)
                return false;
            if(root->left->right!=NULL&&root->left->right->val>root->val)
                return false;
        }
         
        if(root->right!=NULL&&root->right->val<root->val)
            return false;
             
        return checkBST(root->left) && checkBST(root->right);
    }
};

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市老翘,隨后出現(xiàn)的幾起案子芹啥,更是在濱河造成了極大的恐慌锻离,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件墓怀,死亡現(xiàn)場(chǎng)離奇詭異汽纠,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)傀履,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門虱朵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人钓账,你說(shuō)我怎么就攤上這事碴犬。” “怎么了梆暮?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵翅敌,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我惕蹄,道長(zhǎng)蚯涮,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任卖陵,我火速辦了婚禮遭顶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泪蔫。我一直安慰自己棒旗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布撩荣。 她就那樣靜靜地躺著铣揉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪餐曹。 梳的紋絲不亂的頭發(fā)上逛拱,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音台猴,去河邊找鬼朽合。 笑死,一個(gè)胖子當(dāng)著我的面吹牛饱狂,可吹牛的內(nèi)容都是我干的曹步。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼休讳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼讲婚!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起俊柔,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤筹麸,失蹤者是張志新(化名)和其女友劉穎纳猫,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體竹捉,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芜辕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年侵续,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了憨闰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖泽示,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捎泻,我是刑警寧澤埋哟,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布赤赊,位于F島的核電站抛计,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏录豺。R本人自食惡果不足惜饭弓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一媒抠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧趴生,春花似錦昏翰、人聲如沸刘急。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)据块。三九已至,卻和暖如春另假,著一層夾襖步出監(jiān)牢的瞬間边篮,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凶杖,地道東北人智蝠。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓杈湾,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親殴泰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子浮驳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

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

  • 樹(shù)的概述 樹(shù)是一種非常常用的數(shù)據(jù)結(jié)構(gòu)至会,樹(shù)與前面介紹的線性表离咐,棧,隊(duì)列等線性結(jié)構(gòu)不同,樹(shù)是一種非線性結(jié)構(gòu) 1.樹(shù)的定...
    Jack921閱讀 4,452評(píng)論 1 31
  • 紅黑樹(shù)(英語(yǔ):Red–black tree)是一種自平衡二叉查找樹(shù)昆著,是在計(jì)算機(jī)科學(xué)中用到的一種數(shù)據(jù)結(jié)構(gòu),典型的用途...
    卡巴拉的樹(shù)閱讀 15,200評(píng)論 11 113
  • 去年二叉樹(shù)算法的事情鬧的沸沸揚(yáng)揚(yáng)凑懂,起因是Homebrew 的作者 @Max Howell 在 twitter 上發(fā)...
    Masazumi柒閱讀 1,597評(píng)論 0 8
  • 二叉樹(shù)-你必須要懂!(二叉樹(shù)相關(guān)算法實(shí)現(xiàn)-iOS) http://www.cnblogs.com/manji/p/...
    漢秋閱讀 1,863評(píng)論 0 16
  • 在這里梧宫,希望喜歡它的人一起每日感悟人生哲理,為你的生活多一點(diǎn)改變祟敛。 1疤坝、夜,有它特別的氣息馆铁,寂靜跑揉,有它自己的聲音。...
    林窗鯨落閱讀 289評(píng)論 0 0