给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
思路:
显示程序健壮性判断,即判断传进来的二叉树是否为空,不为空的话判断二叉树是否有左右子节点,有的话,先取左子节点的最远右叶子节点,判断是否大于根节点。然后再取右子节点最远的左子节点
基本上如果在左节点的时候不用考虑左子节点是否大于根节点,因为在该节点没有子节点的时候会进行判断。
public boolean isValidBST(TreeNode root) {
if (root == null) return true;
if (root.left != null) {
TreeNode cur = root.left;//每次都会取到每个左子树的根节点
while (cur.right != null) {
cur = cur.right;
}
if (cur.val >= root.val) return false;//判断左子树的右叶子节点会不会大于根节点
}
if (root.right != null) {
TreeNode cur = root.right;//每次都会取到每个右子树的根节点
while (cur.left != null) {//判断右子树的左叶子节点会不会小于于根节点
cur = cur.left;
}
if (cur.val <= root.val) return false;
}
return isValidBST(root.left) && isValidBST(root.right);
}
第二种解法:
跟第一种差不多,只不过我划分成左子树和右子树,不要看没有第一种那么优雅。。但是内存消耗却没有第一次那么多,有一些地方规避了递归。
public boolean isValidBST(TreeNode root) {
if (root == null) return true;
return isBST(root, root.left) && isBSTR(root, root.right);
}
private boolean isBST(TreeNode root, TreeNode node) {
if (root == null) return true;
if (node != null) {
if (node.val >= root.val) return false;
TreeNode cur = node;
while (cur.right != null) {
cur = cur.right;
}
if (cur.val >= root.val) return false;
}
if (root.right != null) {
TreeNode cur = root.right;
while (cur.left != null) {
cur = cur.left;
}
if (cur.val <= root.val) return false;
}
if (root.left != null) return isBST(root.left, root.left.left);
return true;
}
private boolean isBSTR(TreeNode root, TreeNode node) {
if (root == null) return true;
if (node != null) {
if (node.val <= root.val) return false;
TreeNode cur = node;
while (cur.left != null) {
cur = cur.left;
}
if (cur.val <= root.val) return false;
}
if (root.left != null) {
TreeNode cur = root.left;
while (cur.right != null) {
cur = cur.right;
}
if (cur.val >= root.val) return false;
}
if (root.right!= null) return isBSTR(root.right, root.right.right);
return true;
}