[Leetcode] 450. Delete Node in a BST 解题报告

题目

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:

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

Note: Time complexity should be O(height of tree).

Example:

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

    5
   / \
  3   6
 / \   \
2   4   7

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 following BST.

    5
   / \
  4   6
 /     \
2       7

Another valid answer is [5,2,6,null,4,null,7].

    5
   / \
  2   6
   \   \
    4   7

思路

我们的思路是:如果当前的key小于当前root值,则递归删除左子树;如果当前key大于当前root值,则递归删除右子树;如果key等于当前值了,那么就需要删除当前的root,可以分为三种情况进行处理:

1)root只有左子树:那么直接删除当前root,返回左子树即可;

2)root只有右子树:那么直接删除当前root,返回右子树即可;

3)如果root同时拥有左右子树:我们找到root中序遍历的下一个节点,并且交换两者的值,然后递归地在root的右子树上删除key即可(当然也可以在左子树上对称地进行处理)。

读者可以通过代码理解递归调用的妙处。此外我还看到一个针对一般二叉树节点删除的代码片段,虽然由于需要同时执行在左子树和右子树上的节点删除,造成一定的计算冗余,但是实现的代码反而更加精炼。

代码

1、针对BST节点删除:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if (!root) {
            return root;
        }
        if (root->val > key) {          // key can only be in left child
            root->left = deleteNode(root->left, key);
        }
        else if (root->val < key) {     // key can only be in right child
            root->right = deleteNode(root->right, key);
        }
        else {                          // we need to delete root now
            if (!root->left) {          // root only have right child
                TreeNode* right = root->right;
                delete root;
                return right;
            }
            else if (!root->right) {    // root only have left child
                TreeNode* left = root->left;
                delete root;
                return left;
            }
            else {                      // root have both left and right children
                TreeNode* successor = findMinNode(root->right); // find the inorder successor (the minimal node in right subtree)
                root->val = successor->val;
                root->right = deleteNode(root->right, successor->val);
            }
        }
        return root;
    }
private:
    TreeNode* findMinNode(TreeNode *root) {
        while (root->left) {
            root = root->left;
        }
        return root;
    }
};

2、针对一般树的节点删除:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if (!root) {
            return NULL;
        }
        if (root->val == key) {
            if (!root->right) {                 // root do not have right child, so we lift the left child
                TreeNode* left = root->left;
                delete root;
                return left;
            }
            else {                              // find the next TreeNode in in-order traversal
                TreeNode* right = root->right;
                while (right->left) {
                    right = right->left;
                }
                swap(root->val, right->val);    
            }
        }
        root->left = deleteNode(root->left, key);
        root->right = deleteNode(root->right, key);
        return root;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值