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.

Example 1:Input: root = [5,3,6,2,4,null,7],

key = 3Output: [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.

  首先对于BST 来说左子树的节点都比根节点小,右子树的节点都比根节点大,由此可以递归寻找到需要删除的节点。

在删除当前节点的时候需要在该节点的子树中寻找替换节点,同时还要保证BST特性,有点像堆的插入和删除,为了保证依旧保持BST特性,那么替换的节点就是左子树的最大值,或者右子树的最小值,按照这个思路可以把代码写出来。

1、复杂版本 想看最优化的代码请看2号答案,但是下面这个答案确确实实是我第一时间想到的写法,deleteNode 用于检索需要删除的节点find_right find_left 分别用于寻找左子树的最大值,或者右子树的最小值,由于需要替换节点所以还保存了前后两个节点用于删除子树,这个写法很麻烦。而且代码没有完全oc,oc了95%,不知道问题在哪儿。


/**
* 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) {
//递归 检索由于是bst 二叉树 根据其特性可以快速查找对应的节点
if(root==nullptr) return nullptr; if(root->val<key){
root->right=deleteNode(root->right,key);
}
else if(root->val>key){
root->left=deleteNode(root->left,key);
}
else if(root->val==key){
// 替换当前节点 需要寻找右子树的最小节点 或者左子树的最大节点
// 如果右子树为空 就得去找左子树 如果左子树为空就得找右子树
TreeNode* node=nullptr;
if(root->right!=nullptr){
node= find_right(root,root->right); //寻找右子树的最小节点
node->left=root->left;
node->right=root->right; }
else if(root->left!=nullptr){
node= find_left(root,root->left); //寻找左子树的最大节点
node->left=root->left;
node->right=root->right;
}
return node;
}
return root;
} TreeNode* find_right(TreeNode* node,TreeNode* node1){
//存储最后两个节点
TreeNode* root=node;
while(node1->left!=nullptr){
node=node1;
node1=node1->left;
}
if(node==root){
node->right=node1->right;
}
else{
node->left=node1->left;
}
return node1; } TreeNode* find_left(TreeNode* node,TreeNode* node1){
//存储最后两个节点
TreeNode* root=node;
while(node1->right!=nullptr){
node=node1;
node1=node1->right; //寻找左子树最大的数
}
if(node==root){
node->left=node1->left;
}
else{
node->right=node1->right;
}
return node1;
}
};

  2、优化版本,在替换节点的时候可以分三种情况判断以下,(1)无左右子树、(2)只有左子树或者右子树(只要的话删除当前节点即可)、(3)同时有左子树或者右子树,替换后再调用一次deleteNode 即可

/**
* 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) {
//递归 检索由于是bst 二叉树 根据其特性可以快速查找对应的节点
if(root==nullptr) return nullptr; if(root->val<key){
root->right=deleteNode(root->right,key);
}
else if(root->val>key){
root->left=deleteNode(root->left,key);
}
else if(root->val==key){
// 替换当前节点 需要寻找右子树的最小节点 或者左子树的最大节点
// 分三种情况讨论论
// 1 当前节点没有左右子树
if(!root->left && !root->right) return nullptr;
// 2 当前节点只有左子树 或者右子树
else if(!root->left || !root->right)
return root->left ? root->left:root->right;
// 3 当前节点同时有 左子树和右子树 则用左子树的最大节点替换当前节点
TreeNode* node=root->left;
while(node->right!=nullptr) node=node->right;
// 替换当前节点
root->val=node->val;
//但是还要 删除掉这个最右边的节点 下边这个复杂的答案是同时存储两个节点 手动删除
//但是 仔细思考一下 删除这个最右边的节点不就是再调用一遍deleteNode 函数嘛?
root->left=deleteNode(root->left,node->val); }
return root;
} };

【leetcode】 450. Delete Node in a BST的更多相关文章

  1. 【LeetCode】450. Delete Node in a BST 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 迭代 日期 题目地址:https://leetcode ...

  2. 【LeetCode】237. Delete Node in a Linked List 解题报告 (Java&Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 设置当前节点的值为下一个 日期 [LeetCode] ...

  3. 【LeetCode】237. Delete Node in a Linked List

    题目: Write a function to delete a node (except the tail) in a singly linked list, given only access t ...

  4. LeetCode OJ 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. Retur ...

  5. 【leetcode】955. Delete Columns to Make Sorted II

    题目如下: We are given an array A of N lowercase letter strings, all of the same length. Now, we may cho ...

  6. [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. Retur ...

  7. 【一天一道LeetCode】#237. Delete Node in a Linked List

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Write a ...

  8. [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. Retur ...

  9. 【leetcode】1273. Delete Tree Nodes

    题目如下: A tree rooted at node 0 is given as follows: The number of nodes is nodes; The value of the i- ...

随机推荐

  1. hdu 1160 FatMouse's Speed(最长不下降子序列+输出路径)

    题意: FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to ...

  2. 关于docker中容器可以Ping通外网,真机无法Ping通容器的问题

    首先我们要知道整体的框架结构,docker是我们安装在centos7上的,而centos7是安装在vmware上.其中docker中还有若干容器运行. 整体框架图如下: 我们将它分为两部分,一部分是d ...

  3. 【Azure 存储服务】如何把开启NFS 3.0协议的Azure Blob挂载在Linux VM中呢?(NFS: Network File System 网络文件系统)

    问题描述 如何把开启NFS协议的Azure Blob挂载到Linux虚拟机中呢? [答案]:可以使用 NFS 3.0 协议从基于 Linux 的 Azure 虚拟机 (VM) 或在本地运行的 Linu ...

  4. 欢迎加入XiyouLinuxGroup邮件列表

    一:为什么要使用邮件列表? 与QQ,微信等即时通讯的交流方式相比,使用邮件列表交流有以下好处: 保存性好,易于阅读.它能将一个问题讨论的过程完全保存下来,但是QQ的话,聊天记录很容易就刷没了,再也无法 ...

  5. 编译原理中Follow集的求法

    经过前阵子的各种百度以及对课本的反复研究,终于弄明白了follow集的求法,下面记录一下! 首先引用龙书里面的一段较为公式化的follow集求法的话: 计算所有非终结符号A的follow(A)集合时, ...

  6. RF运行之后控制信息日志显示乱码(解决方法)

    RIDE运行自动化测试案例时,控制台信息显示乱码,如下所示: 解决方法:进入到python的安装路径下:D:\python37\Lib\site-packages\robotide\contrib\t ...

  7. 学习JS的第三天

    一.逻辑分支(续) 1.三目运算符:条件运算符 a>b?c:d;表达式1?表达式2:表达式3; 根据表达式1执行的结果,来决定执行表达式2还是表达式3 表达式1结果是true执行表达式2,最终返 ...

  8. JAVA POI导出EXCEL 动态表头、多级表头、动态数据

    导出Excel文件是业务中经常遇到的需求,以下是经常遇到的一些问题: 1,导出中文文件名乱码 String filename = "sheet1";response.setChar ...

  9. 第六周PTA笔记 括号匹配调整+堆放石子+最大积分+168

    括号匹配调整 如果通过插入" +"和" 1"可以从中得到格式正确的数学表达式,则将带括号的序列称为正确的. 例如,序列 "(())()",& ...

  10. Django笔记&教程 6-1 表单(Form)介绍

    Django 自学笔记兼学习教程第6章第1节--表单(Form)介绍 点击查看教程总目录 1 介绍 如果网站要让用户输入并提交数据(比如注册登录),则需要用到表单. 单纯的html也能写出表单,格式一 ...