解题(失败)
思路
- 分别遍历左右子树,用pre存储上一个节点,作比较
代码
public boolean isValidBST(TreeNode root) {
boolean ans =true;
if(root==null) return true;
if (root.left == null && root.right == null) return true;
if(root.left!=null){
if(root.left.val>=root.val) return false;
ans=isLeftSubValid(root.left,root);
}
if(root.right!=null){
if(root.right.val<=root.val) return false;
ans=isRightSubValid(root.right,root);
}
return ans;
}
public boolean isLeftSubValid(TreeNode node,TreeNode pre){
if(node.left!=null){
if(node.left.val>=node.val||(node!=pre&&node.left.val>=pre.val)){
return false;
}
pre=node;
isLeftSubValid(node.left,pre);
}
if(node.right!=null){
if(node.right.val<=node.val||(node!=pre&&node.right.val>=pre.val)){
return false;
}
pre=node;
isLeftSubValid(node.right,pre);
}
return true;
}
public boolean isRightSubValid(TreeNode node,TreeNode pre){
if(node.left!=null){
if(node.left.val>=node.val||(node!=pre&&node.left.val<=pre.val)){
return false;
}
pre=node;
isRightSubValid(node.left,pre);
}
if(node.right!=null){
if(node.right.val<=node.val||(node!=pre&&node.right.val<=pre.val)){
return false;
}
pre=node;
isRightSubValid(node.right,pre);
}
return true;
}
- 本想把左右子树判断函数合并,但运行结果是错的,问题复杂化了,思路有问题
优解
思路
- 中序遍历时,判断当前节点是否大于中序遍历的前一个节点,如果大于,说明满足BST,继续遍历;否则直接返回false
代码
class Solution{
long pre=Long.Min_VALUE;
public boolean isValidBST(TreeNode root){
if(root==null){
return true;
}
//访问左子树
if(!isValidBST(root.left)){
return false;
}
//访问当前节点:如果当前节点小于等于中序遍历的前一个节点,说明不满足BST,返回false;否则继续遍历
if(root.val<=pre){
return false;
}
pre=root.val;
//访问右子树
return isValidBST(root.right);
}
}
小结
- 做题前缺乏思考 ,这么明显的规律,唉,太菜了。做题中想到中序遍历 ,但一根筋地往原思路钻,导致问题的复杂化,这是大忌。
- 对递归思想还是没有足够的把握
二叉排序树(二叉搜索树或二叉查找树)
一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
(4)没有键值相等的结点。