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. Arthas在线java进程诊断工具 在线调试神器

    tag: java 诊断 堆栈 在线调试 耗时 死锁 arthas 阿里巴巴 Arthas (阿尔萨斯) Arthas 是 Alibaba 开源的Java诊断工具,深受开发者喜爱. 官网文档:http ...

  2. journalctl常用命令

    journalctl -xe 查看全部日志# 以flow形式查看日志 $ journalctl -f # 查看内核日志 $ journalctl -k # 查看指定服务日志 $ journalctl ...

  3. PTA 根据后序和中序遍历输出先序遍历 (25分)

    PTA 根据后序和中序遍历输出先序遍历 (25分) 本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果. 输入格式: 第一行给出正整数N(≤30),是树中结点的个数.随后两行 ...

  4. feign微服务调用携带浏览器信息(header、cookie)

    import feign.RequestInterceptor; import feign.RequestTemplate; import org.apache.commons.collections ...

  5. Android Thermal HAL 降龙十八掌

    基本概念 参阅下面两篇文章,就可以大概了解一些概念的内容了 https://source.android.com/devices/architecture/hidl/thermal-mitigatio ...

  6. 解决SpringBoot项目部署到服务器后访问Tomcat后404,无法访问Controller

  7. GoLang设计模式15 - 策略模式

    策略模式是一种行为型设计模式.通过策略模式,可以在运行时修改一个对象的行为. 接下来仍然是通过例子来了解策略模式.比如说内存缓存,这是我们在开发中经常使用的东西,大家应该都有一定的了解,接下来就用内存 ...

  8. FZU ICPC 2020 寒假训练 4 —— 模拟(一)

    P1042 乒乓球 题目背景 国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及.其中11分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役.华华 ...

  9. Python基础(返回函数)

    #我们在函数lazy_sum中又定义了函数f1,并且,内部函数f1可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数f1时,相关参数和变量都保存在返回的函数中,这种称为&qu ...

  10. zookeeper问题在公司可以 回到家用家里网不行 目前还没有解决

    Opening socket connection to server 192.168.1.193/192.168.1.193:2181. Will not attempt to authentica ...