问题描述:
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:
- Search for a node to remove.
- 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
解题思路:
首先考虑是否会出现树中不含有目标节点的情况:
若不含目标节点,则可以直接返回root,我们可以用一个bool值来标志是否找到目标节点。
找到目标节点后,目标节点可能出现的位置:
1.根节点
2.树中
3.叶子节点
其实无论如何我们要做的首先是融合目标节点的子树,那么此时又有4中情况:
1.两个子树都不存在(即叶子节点):返回null
2.只存在一个子树:存在左子树或右子树,这个时候融合结果为存在的那一课子树,则我们可以直接返回存在的子树
3.两个子树都存在:我的选择是将右子树加到左子树的最右的叶子节点。
此时我们有融合好的新的子树的根节点:newRoot
若我们删除的是根节点:则直接返回newRoot
其他的则可以将融合后的新子树附加到原来节点的位置上
代码:
/** * 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; stack<TreeNode*> stk; TreeNode* cur = root; TreeNode* pre = NULL; bool findIt = false; while(cur || !stk.empty()){ if(cur){ if(cur->val == key){ findIt = true; break; } pre = cur; stk.push(cur); cur = cur->left; }else{ cur = stk.top(); pre = cur; stk.pop(); cur = cur->right; } } if(findIt){ TreeNode* newRoot = UnionSubTree(cur); if(pre){ if(cur->val > pre->val){ pre->right = newRoot; }else{ pre->left = newRoot; } }else{ root = newRoot; } } return root; } TreeNode* UnionSubTree(TreeNode* root){ if(!root->left && !root->right) return NULL; else if(root->left && !root->right) return root->left; else if(!root->left && root->right) return root->right; TreeNode* unionPoint = root->left; while(unionPoint->right) unionPoint = unionPoint->right; unionPoint->right = root->right; return root->left; } };