题目
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入: root = [2,1,3]
输出: true
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码
法一:递归
public class Leetcode98 {
/**
* 递归
*
* @param root
* @return
*/
public boolean isValidBST(TreeNode root) {
// 核心利用:维护一个最大值,左子树都要小于这个值,维护一个最小值,右子树都要大于这个值(最小值最大值都是root.val)
return isValidBSTSun(root, Long.MAX_VALUE, Long.MIN_VALUE);
}
private boolean isValidBSTSun(TreeNode root, long maxValue, long minValue) {
if (null == root) {
return true;
}
// 相等也不行
if (root.val >= maxValue) {
return false;
}
if (root.val <= minValue) {
return false;
}
return isValidBSTSun(root.left, root.val, minValue) && isValidBSTSun(root.right, maxValue, root.val);
}
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {
}
TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
}
法二:中序遍历
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
Long pre = Long.MIN_VALUE;
while (!stack.isEmpty() || null!=root){
// 因为中序遍历为 左->中->you;先找到最左节点
while (null!=root){
stack.add(root);
root = root.left;
}
// 拿出最左节点;因为这个节点的左节点是null(循环推出的条件),所以直接处理当前节点和其右子树即可
TreeNode pop = stack.pop();
if(pop.val<=pre){
return false;
}
// 对右子树也进行一套这个流程
pre = Long.valueOf(pop.val);
root = pop.right;
}
return true;
}
解析
法一:递归,递归第一反应就可以解决子树也是二叉搜索树这个条件;关键在于如何递归满足左<root<右这个条件;对于每一个节点,都是大小范围,如果是顶节点,范围就是MIN_VALUE-MAX_VALUE,其他结点,按照是上个节点的左节点还是右节点,来更新max和min即可
法二:中序遍历, 从二叉搜索树的性质可以得出,对二叉搜索树进行中序遍历以后,得到的一定是一个递增的数组;从而 我们可以判断,中序遍历期间,如果出现非递增,则不是二叉搜索树;
中序遍历的方式前面实现过,这里利用栈来做(迭代)
具体的看代码