五分鐘看懂一道中等難度的算法題

來自公眾號:五分鐘學(xué)算法
作者P.yh

今天分享的題目來源于 LeetCode 第 450 號問題:刪除二叉搜索樹中的節(jié)點丸边。雖然它的難度是 中等叠必,但實際上很好理解,請往下看妹窖!

題目描述

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

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

  • 首先找到需要刪除的節(jié)點蜓萄;

  • 如果找到了隅茎,刪除它。

說明:要求算法時間復(fù)雜度為 O(h)嫉沽,h 為樹的高度辟犀。

示例:

root = [5,3,6,2,4,null,7]
key = 3

    5
   / \
  3   6
 / \   \
2   4   7

給定需要刪除的節(jié)點值是 3,所以我們首先找到 3 這個節(jié)點绸硕,然后刪除它堂竟。

一個正確的答案是 [5,4,6,2,null,null,7], 如下圖所示魂毁。


    5
   / \
  4   6
 /     \
2       7

另一個正確答案是 [5,2,6,null,4,null,7]。


    5
   / \
  2   6
   \   \
    4   7

題目解析

在二叉搜索樹上刪除一個節(jié)點跃捣,這道題目有一個隱含的條件漱牵,就是樹上節(jié)點的值不重復(fù)夺蛇。

另外題目還要求時間復(fù)雜度需要保證 O(h) 這里的 h 表示的是二叉樹的高度疚漆。

其實這個題目是分成兩個步驟的,第一個是找到對應(yīng)的節(jié)點刁赦,第二個是刪除節(jié)點娶聘。

因為是二叉搜索樹,對于樹上每個節(jié)點來說甚脉,其 右子樹的節(jié)點都要大于其左子樹的節(jié)點丸升,那么要找對應(yīng)節(jié)點,我們可以從根節(jié)點開始牺氨,一路比較狡耻,大的話就去右邊找,小的話就去左邊找猴凹,這樣每次我們都往下夷狰,可以保證時間復(fù)雜度是 O(h)

當(dāng)我們找到了要刪除的節(jié)點郊霎,在刪除這一步就會有很多的細節(jié)沼头,主要是因為我們需要調(diào)整余下的結(jié)構(gòu),以維持二叉搜索樹的性質(zhì)书劝。

針對這個問題进倍,我們可以分情況討論:

        5
       / \
      3   6
     / \   \
    2   4   7
   /         \
  1           8
  • 情況 1:當(dāng)刪除的節(jié)點沒有左右子樹,比如上圖的 4购对、8猾昆、1
    這時直接刪除即可,樹依舊可以保持二叉搜索樹的性質(zhì)

  • 情況 2:當(dāng)刪除的節(jié)點有左子樹沒有右子樹骡苞,比如上圖的 2
    這時我們只需要將整個左子樹移到當(dāng)前位置即可
    也就是將左子樹的根節(jié)點放到刪除節(jié)點的位置垂蜗,其余不變

  • 情況 3:當(dāng)刪除的節(jié)點沒有左子樹有右子樹,比如上圖的 6烙如、7
    這時我們只需要將整個右子樹移到當(dāng)前位置即可
    也就是將右子樹的根節(jié)點放到刪除節(jié)點的位置么抗,其余不變

  • 情況 4:當(dāng)刪除的節(jié)點既有左子樹又有右子樹,比如上圖的 5亚铁、3
    這時就有兩種方法供選擇:
    去到左子樹中蝇刀,找到值最大節(jié)點,將右子樹全部移到這個節(jié)點下
    去到右子樹中徘溢,找到值最小節(jié)點吞琐,將左子樹全部移到這個節(jié)點下

通過上面的討論分析捆探,我們有了大致的思路。在實現(xiàn)方面站粟,我們可以借助遞歸來巧妙地達到刪除對應(yīng)節(jié)點的目的黍图。

圖片描述

image
image
image
image
image
image
image
image
image
image

參考代碼

//五分鐘學(xué)算法
public TreeNode deleteNode(TreeNode root, int key) {
    if (root == null) {
        return null;
    }

    // 當(dāng)前遍歷到的節(jié)點大于要找的節(jié)點,去左邊繼續(xù)找
    if (root.val > key) {
        root.left = deleteNode(root.left, key);
    }
    // 當(dāng)前遍歷到的節(jié)點小于要找的節(jié)點奴烙,去右邊繼續(xù)找
    else if (root.val < key) {
        root.right = deleteNode(root.right, key);
    } 
    // 找到要刪除的節(jié)點助被,進行刪除操作
    else {
        // 情況 1 & 2
        if (root.right == null) {
            return root.left;
        } 

        // 情況 3
        if (root.left == null) {
            return root.right;
        }

        // 去到刪除節(jié)點的右子樹,找到值最小的節(jié)點
        TreeNode rightSmallest = root.right;
        while (rightSmallest.left != null) {
            rightSmallest = rightSmallest.left;
        }

        // 將刪除節(jié)點的左子樹全部移到這個節(jié)點下
        rightSmallest.left = root.left;

        // 返回右子樹的根節(jié)點切诀,放到當(dāng)前刪除節(jié)點的位置
        return root.right;
    }

    return root;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末揩环,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子幅虑,更是在濱河造成了極大的恐慌丰滑,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件倒庵,死亡現(xiàn)場離奇詭異褒墨,居然都是意外死亡,警方通過查閱死者的電腦和手機擎宝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門郁妈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人认臊,你說我怎么就攤上這事圃庭。” “怎么了失晴?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵剧腻,是天一觀的道長。 經(jīng)常有香客問我涂屁,道長书在,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任拆又,我火速辦了婚禮儒旬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帖族。我一直安慰自己栈源,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布竖般。 她就那樣靜靜地躺著甚垦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上艰亮,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天闭翩,我揣著相機與錄音,去河邊找鬼迄埃。 笑死疗韵,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的侄非。 我是一名探鬼主播蕉汪,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼彩库!你這毒婦竟也來了肤无?” 一聲冷哼從身側(cè)響起先蒋,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤骇钦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后竞漾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體眯搭,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年业岁,在試婚紗的時候發(fā)現(xiàn)自己被綠了鳞仙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡笔时,死狀恐怖棍好,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情允耿,我是刑警寧澤借笙,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站较锡,受9級特大地震影響业稼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蚂蕴,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一低散、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骡楼,春花似錦熔号、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春祠乃,著一層夾襖步出監(jiān)牢的瞬間梦重,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工亮瓷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留琴拧,地道東北人。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓嘱支,卻偏偏與公主長得像蚓胸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子除师,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,585評論 2 359