题目
题解
重新复习一下二叉搜索树的性质:
- 左子树的所有节点(如果有)的值均小于当前节点的值;
- 右子树的所有节点(如果有)的值均大于当前节点的值;
- 左子树和右子树均为二叉搜索树。
二叉搜索树的题目往往可以用递归来解决。 查找结点比较容易,左小右大即可,问题是如何删除结点并保持有序性呢?根据结点的位置不同可以分为以下几种情况:
- root为叶,直接删除
- root有左无右,左子树作为新的子树
- root有右无左,右子树作为新的子树
- root左右双全,这时可以将root的后继结点successor(即右子树中的最小结点)作为新的根节点,并将successor从右子树中删除,之后合并左右子树。
递归
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root==null)
return null;
if(root.val>key) root.left=deleteNode(root.left,key);
else if(root.val<key) root.right=deleteNode(root.right,key);
//找到要删除的结点
else{
if(root.right==null&&root.left==null)
return null;
if(root.right==null)
return root.left;
if(root.left==null)
return root.right;
//左右都不空
else{
TreeNode successor=root.right;
//找到根节点的后继结点
while(successor.left!=null)
successor=successor.left;
root.right=deleteNode(root.right,successor.val);//删除后继结点
successor.left=root.left;
successor.right=root.right;
return successor;
}
}
return root;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n),递归所需的空间复杂度
p.s 现在觉得最麻烦的题就是树的题了…