给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:
2
/ \
1 3
输出: true
示例 2:
输入:
5
/ \
1 4
/ \
3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。
解法一:
可以利用它本身的性质来做,即 左 < 根 < 右,初始化时带入系统最大值和最小值,在递归过程中换成它们自己的节点值,用 long 代替 int 就是为了包括 int 的边界条件。
public boolean isValidBST(TreeNode root) {
if (root == null) return true;
return valid(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
public boolean valid(TreeNode root, long low, long high) {
if (root == null) return true;
if (root.val <= low || root.val >= high) return false;
return valid(root.left, low, root.val) && valid(root.right, root.val, high);
}
解法二:
下面我们使用中序遍历来做,这种方法思路很直接,通过中序遍历将所有的节点值存到一个数组里,然后再来判断这个数组是不是有序的。
public boolean isValidBST(TreeNode root) {
List<Integer> list = new ArrayList<Integer>();
inOrder(root, list);
for (int i = 0; i < list.size() - 1; ++i) {
if (list.get(i) >= list.get(i + 1)) return false;
}
return true;
}
public void inOrder(TreeNode node, List<Integer> list) {
if (node == null) return;
inOrder(node.left, list);
list.add(node.val);
inOrder(node.right, list);
}
解法三:
也可以用非递归来做,需要用到栈,因为中序遍历可以非递归来实现,所以只要在其上面的代码稍加改动就可以了。
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> s = new Stack<TreeNode>();
TreeNode p = root, pre = null;
while (p != null || !s.empty()) {
while (p != null) {
s.push(p);
p = p.left;
}
TreeNode t = s.pop();
if (pre != null && t.val <= pre.val) return false;
pre = t;
p = t.right;
}
return true;
}