给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。
一般来说,删除节点可分为两个步骤:
首先找到需要删除的节点;
如果找到了,删除它。
说明: 要求算法时间复杂度为 O(h),h 为树的高度。
示例:
root = [5,3,6,2,4,null,7]
key = 3
5
/ \
3 6
/ \ \
2 4 7
给定需要删除的节点值是 3,所以我们首先找到 3 这个节点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7], 如下图所示。
5
/ \
4 6
/ \
2 7
另一个正确答案是 [5,2,6,null,4,null,7]。
5
/ \
2 6
\ \
4 7
思路:dfs遍历一遍找到key,然后存储key结点的左子树将其加到key右子树的最左边就ok了。
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Solution {
private boolean mark;
private TreeNode one,two;
public TreeNode deleteNode(TreeNode root, int key) {
if(root==null) return null;
mark=false;
one=two=null;
if(root.val==key && root.right==null) return root.left;
dfs(root,null,-1,key);
if(root.val==key) return root.right;
return root;
}
private void dfs(TreeNode root,TreeNode p,int id,int key) {
if(root==null || mark) return;
if(root.val<key) dfs(root.right,root,1,key);
else if(root.val>key) dfs(root.left,root,0,key);
else {
if(root.right==null) {
if(id==0) p.left=root.left;
else if(id==1) p.right=root.left;
}
else {
mark=true;
TreeNode tmp=root.left;
root.left=null;
if(id==0) p.left=root.right;
else if(id==1) p.right=root.right;
root=root.right;
while(root.left!=null) {
root=root.left;
}
root.left=tmp;
}
}
}
}