算法訓(xùn)練第二十二天|第六章 二叉樹

  • 235 二叉搜索樹的最近公共祖先
  • 701 二叉搜索樹中的插入操作
  • 450 刪除二叉搜索樹中的節(jié)點

235. 二叉搜索樹的最近公共祖先

給定一個二叉搜索樹, 找到該樹中兩個指定節(jié)點的最近公共祖先。

百度百科中最近公共祖先的定義為:“對于有根樹 T 的兩個結(jié)點 p梅肤、q楞陷,最近公共祖先表示為一個結(jié)點 x侠讯,滿足 x 是 p吆录、q 的祖先且 x 的深度盡可能大(一個節(jié)點也可以是它自己的祖先)柔吼≡砉桑”

方法一: 遞歸寫法

如果 cur->val 小于 p->val荷辕,同時 cur->val 小于 q->val途戒,那么就應(yīng)該向右遍歷(目標區(qū)間在右子樹)坑傅。反之,向左遍歷喷斋。
剩下的情況唁毒,就是cur節(jié)點在區(qū)間,那么cur就是最近公共祖先了继准,直接返回cur


class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //遞歸三要素: 確定終止條件
        if(root == null) return root;
        
        //遞歸三要素: 單層邏輯
        if(root.val > p.val && root.val > q.val){ //root值大于p,q枉证,向左尋找
           return lowestCommonAncestor(root.left, p, q); 
        }else if(p.val > root.val && q.val > root.val){ //root值小于p,q,向右尋找
            return lowestCommonAncestor(root.right, p, q);
        }else{//root 位于p,q之間,root就是lowest Common Ancestor
            return root;
        }
    }
}

方法二 . 迭代

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null) return root;
        
        while(true){
            if(root.val > p.val && root.val > q.val){
                root = root.left;
            }else if(root.val < p.val && root.val < q.val){
                root = root.right;
            }else{
                break;
            }
        }
        return root;
    }
}

時間復(fù)雜度: O(n)
空間復(fù)雜度: O(1)

701. 二叉搜索樹中的插入操作

給定二叉搜索樹(BST)的根節(jié)點和要插入樹中的值移必,將值插入二叉搜索樹室谚。 返回插入后二叉搜索樹的根節(jié)點。 輸入數(shù)據(jù)保證,新值和原始二叉搜索樹中的任意節(jié)點值都不同秒赤。

思路: 只要按照二叉搜索樹的規(guī)則去遍歷猪瞬,遇到空節(jié)點就插入節(jié)點就可以了。

遞歸:

  • 確定終止條件
    終止條件就是找到遍歷的節(jié)點為null的時候入篮,就是要插入節(jié)點的位置了陈瘦,并把插入的節(jié)點返回。
  • 確定單層遞歸的邏輯
    根據(jù)BST特性潮售,如果root.val < val, 說明val應(yīng)該出現(xiàn)在root右側(cè)痊项,向右子樹尋找; 反之向左尋找
class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null) return new TreeNode(val);
        if(root.val < val){ 
            root.right = insertIntoBST(root.right, val);
        }else{
            root.left = insertIntoBST(root.left, val);
        }
        return root;
    }
}

迭代:
在迭代法遍歷的過程中酥诽,需要記錄一下當前遍歷的節(jié)點的父節(jié)點鞍泉,這樣才能做插入節(jié)點的操作

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null) return new TreeNode(val);
        TreeNode cur = root;
        TreeNode pre = root; //當前遍歷的節(jié)點的父節(jié)點

        while(cur != null){
            pre = cur;
            if(cur.val > val){
                cur = cur.left;
            }else{
                cur = cur.right;
            }
        }
        if(pre.val > val){
            pre.left = new TreeNode(val);
        }else{
            pre.right = new TreeNode(val);
        }
        return root;
    }
}

時間復(fù)雜度:O(N),其中 N 為樹中節(jié)點的數(shù)目肮帐。最壞情況下咖驮,我們需要將值插入到樹的最深的葉子結(jié)點上,而葉子節(jié)點最深為 O(N)训枢。
空間復(fù)雜度:O(1)托修。我們只使用了常數(shù)大小的空間。

450. 刪除二叉搜索樹中的節(jié)點

給定一個二叉搜索樹的根節(jié)點 root 和一個值 key恒界,刪除二叉搜索樹中的 key 對應(yīng)的節(jié)點睦刃,并保證二叉搜索樹的性質(zhì)不變。返回二叉搜索樹(有可能被更新)的根節(jié)點的引用仗处。

一般來說眯勾,刪除節(jié)點可分為兩個步驟:

首先找到需要刪除的節(jié)點;
如果找到了婆誓,刪除它吃环。

刪除節(jié)點的五種情況:

  1. 樹中沒有需要刪除的節(jié)點
    返回root
  2. 要刪除的節(jié)點是葉子節(jié)點
    直接刪除
  3. 要刪除的節(jié)點左空右不空
    父節(jié)點直接指向右孩子
  4. 要刪除的節(jié)點右空左不空
    父節(jié)點直接指向左孩子
  5. 要刪除的節(jié)點左右均不為空
    左孩子繼位,原來的右子樹成為左孩子的最右葉子的右孩子
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        //沒有找到需要刪除的節(jié)點
        if(root == null) return null;
        
        if(key > root.val){
            // 去右子樹刪除
            root.right = deleteNode(root.right, key);
        }else if(key < root.val){
            // 去左子樹刪除
            root.left = deleteNode(root.left, key);
        }else{
            //key found
            //要刪除的節(jié)點是葉子節(jié)點
            if (root.left == null && root.right == null) {
                return null;
            }
            //要刪除的節(jié)點左空右不空, 父節(jié)點直接指向右孩子
            if(root.left == null) return root.right;
            //要刪除的節(jié)點右空左不空, 父節(jié)點直接指向左孩子
            if(root.right == null) return root.left;
            
            //左右都不為空洋幻,原來的右子樹成為左孩子的最右葉子的右孩子郁轻,左孩子繼位,
            TreeNode cur = root.left;
            while(cur.right != null){
            cur = cur.right;
            } 
            cur.right = root.right;
            root = root.left; // 左孩子頂替被刪除節(jié)點的位置文留,節(jié)點被刪除
            
        }
        return root;
    }
}

時間復(fù)雜度 O(n)
空間復(fù)雜度O(n)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末好唯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子燥翅,更是在濱河造成了極大的恐慌骑篙,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件森书,死亡現(xiàn)場離奇詭異靶端,居然都是意外死亡谎势,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門杨名,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脏榆,“玉大人,你說我怎么就攤上這事台谍⌒胛梗” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵趁蕊,是天一觀的道長坞生。 經(jīng)常有香客問我,道長介衔,這世上最難降的妖魔是什么恨胚? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任骂因,我火速辦了婚禮炎咖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寒波。我一直安慰自己乘盼,他們只是感情好,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布俄烁。 她就那樣靜靜地躺著绸栅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪页屠。 梳的紋絲不亂的頭發(fā)上粹胯,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天,我揣著相機與錄音辰企,去河邊找鬼风纠。 笑死,一個胖子當著我的面吹牛牢贸,可吹牛的內(nèi)容都是我干的竹观。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼潜索,長吁一口氣:“原來是場噩夢啊……” “哼臭增!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起竹习,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤誊抛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后整陌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拗窃,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡昔园,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了并炮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片默刚。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖逃魄,靈堂內(nèi)的尸體忽然破棺而出荤西,到底是詐尸還是另有隱情,我是刑警寧澤伍俘,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布邪锌,位于F島的核電站,受9級特大地震影響癌瘾,放射性物質(zhì)發(fā)生泄漏觅丰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一妨退、第九天 我趴在偏房一處隱蔽的房頂上張望妇萄。 院中可真熱鬧,春花似錦咬荷、人聲如沸冠句。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽懦底。三九已至,卻和暖如春罕扎,著一層夾襖步出監(jiān)牢的瞬間聚唐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工腔召, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杆查,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓宴咧,卻偏偏與公主長得像根灯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子掺栅,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

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