• [JavaScript 刷题] 树 - 删除二叉搜索树中的节点, leetcode 450


    [JavaScript 刷题] 树 - 删除二叉搜索树中的节点, leetcode 450

    github repo 地址: https://github.com/GoldenaArcher/js_leetcode,Github 的目录 大概 会更新的更勤快一些。

    题目地址: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.

    解题思路

    这题主要分为以下这么 4 种情况:

    1. 结点为空

      什么都不需要做,直接返回即可(递归条件中的 base case)

    2. 结点为叶结点

      直接删除即可

    3. 结点只包含左子树或右子树

      使用左子树/右子树代替当前结点即可

    4. 结点包含左右子树

      这个情况是最复杂的,也是解起来比较麻烦的一点,不过这可以利用二叉树的特性:

      • 结点的右子树一定比当前结点大
      • 结点的左子树一定比当前结点小
      • 一棵树最左边的结点是整棵树中的最小值

      来解决这道题。

      bst deletion

      以这张图为例,想要删除的结点为 7,最简单的做法就是将 7 的右子树代替 7:

      bst deletion1

      同时原本的左子树 [5, 4] 挂到 10 的最左结点下:

      bst deletion2

      这个解法利用了上面提到的三个特性,同时也将时间复杂度控制在了 O ( h ) O(h) O(h) 上,但是需要注意的一点就是,在最差情况下,这样的解法可能趋近于 O ( n ) O(n) O(n)——毕竟不是一颗平衡二叉搜索树。

    使用 JavaScript 解题

    /**
     * Definition for a binary tree node.
     * function TreeNode(val, left, right) {
     *     this.val = (val===undefined ? 0 : val)
     *     this.left = (left===undefined ? null : left)
     *     this.right = (right===undefined ? null : right)
     * }
     */
    /**
     * @param {TreeNode} root
     * @param {number} key
     * @return {TreeNode}
     */
    var deleteNode = function (root, key) {
      const dfs = (root) => {
        if (!root) return null;
    
        // 如果找到需要删除的结点
        if (root.val === key) {
          // 只有一棵子树存在,直接返回另外一边即可
          if (!root.left) return root.right;
          if (!root.right) return root.left;
    
          // 如果存在两棵子树
          let curr = root.right;
          // 找到右子树的最左结点
          while (curr.left) curr = curr.left;
          // 将原本的左子树挂载到这里
          curr.left = root.left;
          return root.right;
        }
    
        // search in the right tree
        if (key > root.val) root.right = dfs(root.right);
        else root.left = dfs(root.left);
    
        return root;
      };
    
      return dfs(root);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
  • 相关阅读:
    【简单】 猿人学web第一届 第3题 罗生门
    并查集——奇偶游戏(带边权和扩展域做法)
    细胞凋亡通路 | MedChemExpress
    Git分布式版本控制工具(一)
    Redis安装-Docker
    配置ssh免密登陆:客户端主机通过redhat用户基于秘钥验证方式进行远程连接服务器的root用户
    违反这些设计原则,系统就等着“腐烂”
    promise详解
    开源软件的漏洞响应:应对安全威胁
    牡丹
  • 原文地址:https://blog.csdn.net/weixin_42938619/article/details/125466404