#问题描述
Given a binary tree, determine if it is a valid binary search tree (BST).给定一个二叉树,判断它是否是一个有效的二叉搜索树(BST)。
Assume a BST is defined as follows:
The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than the node’s key.
Both the left and right subtrees must also be binary search trees.
假设BST的定义如下:
节点的左子树的所有结点的键值都小于该节点的键值。
节点的左子树的所有结点的键值都大于该节点的键值。
左子树和右子树也必须是二叉搜索树。
思路
方法1:利用中序遍历有序的特点。
方法2:利用分治的思想。判断左子树和右子树是否是二叉搜索树,以及是否满足节点的左子树的所有结点的键值都小于该节点的键值(只需根节点的值>左子树的最大值),以及满足节点的右子树的所有结点的键值都大于该节点的键值(只需右子树的最小值>根节点的值),所以需要一个内部类ResultType,包含是否为二叉搜索树,左子树的最大值,右子树的最小值。
java实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
/*
//方法1:利用中序遍历有序的特点。
class Solution {
public boolean isValidBST(TreeNode root) {
if(root==null)
return true;
List<Integer> inoder=inorderTraversal(root);
for (int i = 1; i <inoder.size() ; i++) {
if(inoder.get(i)<=inoder.get(i-1))
return false;
}
return true;
}
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null)
return result;
TreeNode current = root;
Stack<TreeNode> stack = new Stack<TreeNode>();
while (current!=null || !stack.isEmpty()) {
while (current != null) {
stack.push(current);
current = current.left;
}
current = stack.pop();
result.add(current.val);
current = current.right;
}
return result;
}
}
*/
/*
方法2:利用分治的思想
因为二叉搜索树满足节点的左子树的所有结点的键值都小于该节点的键值,只需根节点的值>左子树的最大值
因为二叉搜索树满足节点的右子树的所有结点的键值都大于该节点的键值,只需右子树的最小值>根节点的值
左子树和右子树也必须是二叉搜索树。
所以需要ResultType包含是否为二叉搜索树,左子树的最大值,右子树的最小值。
*/
class Solution {
class ResultType{
boolean is_bst;//是否为二叉搜索树
int maxValue,minValue;//左子树的最大值,右子树的最小值
ResultType(boolean is_bst,int maxValue,int minValue){//构造函数
this.is_bst=is_bst;
this.maxValue=maxValue;
this.minValue=minValue;
}
}
//以root为根的二叉树是否为二叉搜索树
public boolean isValidBST(TreeNode root) {
if(root==null)
return true;
ResultType result=validBST(root);
return result.is_bst;
}
//以root为根的二叉树 返回其ResultType(是否为二叉搜索树,左子树的最大值,右子树的最小值)
public ResultType validBST(TreeNode root){
if(root==null)//根为空,是二叉搜索树
return new ResultType(true,Integer.MIN_VALUE,Integer.MAX_VALUE);
//要求max,用Integer.MIN_VALUE;要求min,用Integer.MAX_VALUE
//后面比较Math.min(root.val,left.minValue)的时候用left.minValue为正无穷大,正无穷大的与root.val比,left.minValue被淘汰,不会影响root的正常计算;Integer.MAX_VALUE同理
//用Integer.MIN_VALUE或者Integer.MAX_VALUE而不能用0,因为有可能是负数
ResultType left=validBST(root.left);//左子树返回结果
ResultType right=validBST(root.right);//右子树返回结果
if(!left.is_bst || !right.is_bst)//如果左子树或者右子树不是二叉搜索树,则以root为根的二叉树不是二叉搜索树(因为以root为根的二叉搜索树的左子树和右子树也必须是二叉搜索树。)
return new ResultType(false,0,0);
//如果左边不满足左边都比root小(存在左子树且左子树的最大值>=根节点的值) 或者右边不满足右边都比root大(存在右子树且右子树的最小值<=根节点的值),不是二叉搜索树
if((root.left!=null && left.maxValue>=root.val)||(root.right!=null && right.minValue<=root.val))
return new ResultType(false,0,0);
//是二叉搜索树
return new ResultType(true,Math.max(root.val,right.maxValue),Math.min(root.val,left.minValue));
}
}