LeetCode #450 Delete Node in a BST 刪除二叉搜索樹中的節(jié)點

450 Delete Node in a BST 刪除二叉搜索樹中的節(jié)點

Description:
Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.

Basically, the deletion can be divided into two stages:

Search for a node to remove.
If the node is found, delete the node.

Follow up:
Can you solve it with time complexity O(height of tree)?

Example:

Example 1:

Delete Node 1

Input: root = [5,3,6,2,4,null,7], key = 3
Output: [5,4,6,2,null,null,7]
Explanation: Given key to delete is 3. So we find the node with value 3 and delete it.
One valid answer is [5,4,6,2,null,null,7], shown in the above BST.
Please notice that another valid answer is [5,2,6,null,4,null,7] and it's also accepted.

Example 2:

Delete Node 2

Input: root = [5,3,6,2,4,null,7], key = 0
Output: [5,3,6,2,4,null,7]
Explanation: The tree does not contain a node with value = 0.

Example 3:

Input: root = [], key = 0
Output: []

Constraints:

The number of nodes in the tree is in the range [0, 10^4].
-10^5 <= Node.val <= 10^5
Each node has a unique value.
root is a valid binary search tree.
-10^5 <= key <= 10^5

題目描述:
給定一個二叉搜索樹的根節(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

思路:

遞歸
先通過二叉搜索樹的性質(zhì)查找到需要刪去的節(jié)點

  1. 如果該節(jié)點左右孩子中有一個為空, 則用另一個子樹代替刪除節(jié)點即可
  2. 如果該節(jié)點為葉子節(jié)點, 直接刪除即可
  3. 如果該節(jié)點兩個孩子都存在, 則用右子樹中的最小值來代替該節(jié)點, 因為右子樹中的節(jié)點都大于待刪除節(jié)點, 所以這個最小值一定大于左子樹所有節(jié)點的值, 不會破壞二叉搜索樹的性質(zhì)

查找右子樹的最小值只需要一直往左走到底即可
時間復(fù)雜度O(h), 空間復(fù)雜度O(h), 其中 h為二叉搜索樹的高度, 最小為平衡二叉樹時 h = lgn

代碼:
C++:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution 
{
public:
    TreeNode* deleteNode(TreeNode* root, int key) 
    {
        if (!root) return root;
        if (root -> val > key) root -> left = deleteNode(root -> left, key);
        else if (root -> val < key) root -> right = deleteNode(root -> right, key);
        else
        {
            if (!root -> left or !root -> right) root = root -> left ? root -> left : root -> right;
            else
            {
                TreeNode *cur = root -> right;
                while (cur -> left) cur = cur -> left;
                root -> val = cur -> val;
                root -> right = deleteNode(root -> right, cur -> val);
            }
        }
        return root;
    }
};

Java:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) return root;
        if (root.val > key) root.left = deleteNode(root.left, key);
        else if (root.val < key) root.right = deleteNode(root.right, key);
        else {
            if (root.left == null || root.right == null) root = root.left == null ? root.right : root.left;
            else {
                TreeNode cur = root.right;
                while (cur.left != null) cur = cur.left;
                root.val = cur.val;
                root.right = deleteNode(root.right, cur.val);
            }
        }
        return root;
    }
}

Python:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
        if not root:
            return None
        if root.val > key:
            root.left = self.deleteNode(root.left, key)
        elif root.val < key:
            root.right = self.deleteNode(root.right, key)
        else:
            if not root.left or not root.right:
                root = root.left if root.left else root.right
            else:
                cur = root.right
                while cur.left:
                    cur = cur.left
                root.val = cur.val
                root.right = self.deleteNode(root.right, cur.val)
        return root
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市溜腐,隨后出現(xiàn)的幾起案子坯门,更是在濱河造成了極大的恐慌,老刑警劉巖逗扒,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件古戴,死亡現(xiàn)場離奇詭異,居然都是意外死亡矩肩,警方通過查閱死者的電腦和手機现恼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門肃续,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人叉袍,你說我怎么就攤上這事始锚。” “怎么了喳逛?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵瞧捌,是天一觀的道長。 經(jīng)常有香客問我润文,道長姐呐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任典蝌,我火速辦了婚禮曙砂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘骏掀。我一直安慰自己鸠澈,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布截驮。 她就那樣靜靜地躺著笑陈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪葵袭。 梳的紋絲不亂的頭發(fā)上新锈,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機與錄音眶熬,去河邊找鬼。 笑死块请,一個胖子當(dāng)著我的面吹牛娜氏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播墩新,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼贸弥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了海渊?” 一聲冷哼從身側(cè)響起绵疲,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤憨奸,失蹤者是張志新(化名)和其女友劉穎忧换,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缨称,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡讯沈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年郁岩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡问慎,死狀恐怖萍摊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情如叼,我是刑警寧澤冰木,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站笼恰,受9級特大地震影響踊沸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜挖腰,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一雕沿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧猴仑,春花似錦审轮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至崖飘,卻和暖如春榴捡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背朱浴。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工吊圾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人翰蠢。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓项乒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親梁沧。 傳聞我的和親對象是個殘疾皇子檀何,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

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