给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:
2
/ \
1 3
输出: true
示例 2:
输入:
5
/ \
1 4
/ \
3 6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
根节点的值为 5 ,但是其右子节点值为 4 。
思路与代码
递归法
递归判断左右两个左子树是否都满足在low-high区间中,注意因为TreeNode中的val为int类型,所以函数中我们用Long类型来防止节点中出现Intege.MAX_VALUE 和 Integer.MIN_VALUE的情况。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
if (root == null) return true;
return isValidSon(root.left, Long.MIN_VALUE, root.val) && isValidSon(root.right, root.val, Long.MAX_VALUE);
}
public boolean isValidSon(TreeNode root, long low, long high) {
if (root == null) return true;
if (root.val >= high || root.val <= low) return false;
return isValidSon(root.left, low, Math.min(high, root.val) ) && isValidSon(root.right, Math.max(low, root.val), high);
}
}
中序遍历法
中序遍历正好是从小到大,只需判断中序遍历的结果是不是严格单调增。
class Solution {
public boolean isValidBST(TreeNode root) {
Deque<TreeNode> stack = new LinkedList<TreeNode>();
double inorder = -Double.MAX_VALUE;
while (!stack.isEmpty() || root != null) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
// 如果中序遍历得到的节点的值小于等于前一个 inorder,说明不是二叉搜索树
if (root.val <= inorder) {
return false;
}
inorder = root.val;
root = root.right;
}
return true;
}
}