[leetcode Validate Binary Search Tree]從定義出發(fā)礁哄,理解二叉搜索樹

附上原題:

一棵二叉樹如果屬于二叉搜索樹,必須滿足三個條件:

  1. 左子樹的所有節(jié)點都小于根節(jié)點
  1. 右子樹的所有節(jié)點都大于根節(jié)點
  2. 左子樹跟右子樹同時也是二叉搜索樹

我們看到第三條定義本身也是遞歸的碱妆。那根據(jù)該定義辛馆,如何來檢驗一棵二叉樹到底是不是二叉搜索樹?

首先百宇,如果左子樹跟右子樹其中有一棵不是二叉搜索樹的情況下考廉,則該二叉樹必定不屬于二叉搜索樹。那如何判定左子樹跟右子樹是不是二叉搜索樹呢携御?好像我們又回到了原來的問題昌粤。看一種比較特殊的情況啄刹,假如說二叉樹只有一個節(jié)點涮坐,即沒有左子樹也沒有右子樹,那么它必定屬于二叉搜索樹誓军。如果左子樹不存在袱讹,右子樹存在的情況下呢?此時左子樹就不需要再考慮是不是二叉搜索樹了昵时。反之右子樹不存在的情況下也一樣捷雕。

因此,對于這個問題壹甥,我們可以先考慮一棵二叉樹的葉子節(jié)點救巷。比如說有這樣一棵二叉樹:



左子樹跟右子樹都屬于葉子節(jié)點,必定是二叉搜索樹句柠。在符合第三條定義的情況下浦译,再來看前面兩條。根節(jié)點大于左子樹的所有節(jié)點溯职,難道要用根節(jié)點與左子樹的每個節(jié)點去比較精盅?我們換個角度想,是不是只要根節(jié)點大于左子樹最大的節(jié)點就可以了谜酒?因為在確定左子樹屬于二叉搜索樹的情況下叹俏,只要沿著左子樹的根節(jié)點出發(fā)一直向右即可找到最大的節(jié)點。同樣甚带,對于第二個定義她肯,根節(jié)點只需小于右子樹最小的節(jié)點即可。

我們運用了一種“分而治之”的思想鹰贵,先考慮最基本的情況晴氨,即葉子節(jié)點,再得到左子樹和右子樹同時為二叉搜索樹的前提下碉输,用當前樹的根節(jié)點去比較左子樹的最大值和右子樹的最小值籽前。然后算法不斷得往上回溯,最終得出整棵樹是不是二叉搜索樹。

根據(jù)以上分析枝哄,我們設計出如下算法:

  1. 如果當前節(jié)點即不存在左子樹也不存在右子樹肄梨,直接返回true。
  1. 如果當前節(jié)點存在左子樹挠锥,則驗證左子樹是否為二叉搜索樹众羡,若是,并且根節(jié)點大于左子樹的最大值蓖租,則左子樹驗證通過粱侣。若左子樹不存在,同樣驗證通過蓖宦。
  2. 如果當前節(jié)點存在右子樹齐婴,則驗證右子樹是否為二叉搜索樹,若是稠茂,并且根節(jié)點小于右子樹的最小值柠偶,右子樹驗證通過。若右子樹不存在睬关,同樣驗證通過诱担。
  3. 若左子樹跟右子樹同時驗證通過,返回true共螺;否則该肴,返回false情竹。

看代碼:

class Solution {
public:
    bool isValidBST(TreeNode* root) {

        bool isValidLeft = true;
        bool isValidRight = true;
        if (root) {
            int val = root->val;
            if (root->left) {
                //驗證左子樹是否為二叉搜索樹藐不,并且根節(jié)點大于左子樹的最小值
                isValidLeft = isValidBST(root->left) && (val > fetchMaxNodeVal(root->left));
            }
            if (root->right) {
                isValidRight = isValidBST(root->right) && (val < fetchMinNodeVal(root->right));
            }

            if (!root->left && !root->right) {
                return true;
            }
        }
        return isValidLeft && isValidRight;
    }
private:
    //獲取二叉樹的最大值
    int fetchMaxNodeVal(TreeNode *node) {
        while (node->right) {
            node = node->right;
        }
        return node->val;
    }

    int fetchMinNodeVal(TreeNode *node) {
        while (node->left) {
            node = node->left;
        }
        return node->val;
    }
};
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市秦效,隨后出現(xiàn)的幾起案子雏蛮,更是在濱河造成了極大的恐慌,老刑警劉巖阱州,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挑秉,死亡現(xiàn)場離奇詭異,居然都是意外死亡苔货,警方通過查閱死者的電腦和手機犀概,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來夜惭,“玉大人姻灶,你說我怎么就攤上這事≌┘耄” “怎么了产喉?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我曾沈,道長这嚣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任塞俱,我火速辦了婚禮姐帚,結果婚禮上,老公的妹妹穿的比我還像新娘障涯。我一直安慰自己卧土,他們只是感情好,可當我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布像樊。 她就那樣靜靜地躺著尤莺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪生棍。 梳的紋絲不亂的頭發(fā)上颤霎,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天,我揣著相機與錄音涂滴,去河邊找鬼友酱。 笑死,一個胖子當著我的面吹牛柔纵,可吹牛的內(nèi)容都是我干的缔杉。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼搁料,長吁一口氣:“原來是場噩夢啊……” “哼或详!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起郭计,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤霸琴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后昭伸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梧乘,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年庐杨,在試婚紗的時候發(fā)現(xiàn)自己被綠了选调。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡灵份,死狀恐怖仁堪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情各吨,我是刑警寧澤枝笨,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布袁铐,位于F島的核電站,受9級特大地震影響横浑,放射性物質(zhì)發(fā)生泄漏剔桨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一徙融、第九天 我趴在偏房一處隱蔽的房頂上張望洒缀。 院中可真熱鬧,春花似錦欺冀、人聲如沸树绩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽饺饭。三九已至,卻和暖如春职车,著一層夾襖步出監(jiān)牢的瞬間瘫俊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工悴灵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扛芽,地道東北人。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓积瞒,卻偏偏與公主長得像川尖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子茫孔,可洞房花燭夜當晚...
    茶點故事閱讀 45,747評論 2 361

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