450. 删除二叉搜索树中的节点

Problem: 450. 删除二叉搜索树中的节点

思路

本题如代码随想录所说,有以下五种情况:

第一种情况:没找到删除的节点,遍历到空节点直接返回了
找到删除的节点
第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。

最难理解的是第五种,我来精简一下把左子树放到右子树的最左下,如下图。

image.png

由于我们是需要删除节点的,所以必须要有返回值,告诉上一个节点,他的左孩子/右孩子是什么。

复杂度

时间复杂度:

添加时间复杂度, 示例: $O(n)$

空间复杂度:

添加空间复杂度, 示例: $O(n)$

Code

[]
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
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(root == nullptr) return nullptr;
if(root->val == key) {
if(root->left == nullptr && root->right == nullptr) {
delete root;
return nullptr;
}
if(root->left == nullptr && root->right != nullptr) {
TreeNode* right = root->right;
delete root;
return right;
}
if(root->left != nullptr && root->right == nullptr) {
TreeNode* left = root->left;
delete root;
return left;
}
TreeNode* tmp = root->right;
//左子树放到右子树的最左下
TreeNode* leftDown = root->right;
while(leftDown->left != nullptr) leftDown = leftDown->left;
leftDown->left = root->left;
delete root;
return tmp;
}
root->left = deleteNode(root->left,key);
root->right = deleteNode(root->right,key);
return root;
}
};