Description:
Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
1.The left subtree of a node contains only nodes with keys less than the node’s key.
2.The right subtree of a node contains only nodes with keys greater than the node’s key.
3.Both the left and right subtrees must also be binary search trees.
问题描述
给定一颗树,判断是否为二叉搜索树。。。
二叉搜索树的定义:
1.左子树的所有节点都小于根节点
2.右子树的所有节点都大于根节点
3.左子树和右子树同时也是二叉搜索树
解法一
思路:
二叉搜索树的第3条定义本身也是递归的,这里用递归的思路解决这个问题。
首先,如果左子树根右子树有一颗不是二叉搜索树的情况下,则该二叉树肯定不是二叉搜索树。如何判断左子树跟右子树是不是二叉搜索树呢?又回到了问题的原点。
假如,二叉树既没有左子树也没有右子树,那么一定是二叉搜索树。如果左子树不存在,右子树存在,那么此时就不用考虑左子树是不是二叉搜索树了。
先考虑一棵二叉树的叶子节点,左子树跟右子树都属于叶子节点,必定是二叉搜索树。根节点大于左子树的所有节点等价于根节点大于左子树最大的节点。根节点小于于右子树的所有节点等价于根节点小于右子树最小的节点。
运用了一种“分而治之”的思想,先考虑最基本的情况,即叶子节点,再得到左子树和右子树同时为二叉搜索树的前提下,用当前树的根节点去比较左子树的最大值和右子树的最小值。然后算法不断得往上回溯,最终得出整棵树是不是二叉搜索树。
1.如果当前节点即不存在左子树也不存在右子树,直接返回true。
2.如果当前节点存在左子树,则验证左子树是否为二叉搜索树,若是,并且根节点大于左子树的最大值,则左子树验证通过。若左子树不存在,同样验证通过。
3.如果当前节点存在右子树,则验证右子树是否为二叉搜索树,若是,并且根节点小于右子树的最小值,右子树验证通过。若右子树不存在,同样验证通过。
4.若左子树跟右子树同时验证通过,返回true;否则,返回false。
Code:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isValidBST(TreeNode root) {
boolean isValidLeft = true;
boolean isValidRight = true;
if(root != null){
int val = root.val;
if(root.left != null){
//验证左子树是否为二叉搜索树,并且根节点大于左子树的最大值
isValidLeft = isValidBST(root.left) && (val > fetchMaxNodeVal(root.left));
}
if(root.right != null){
//验证右子树是否为二叉搜索树,并且根节点小于右子树的最小值
isValidRight = isValidBST(root.right) && (val < fetchMinNodeVal(root.right));
}
if(root.left == null && root.right == null){
return true;
}
}
return isValidLeft && isValidRight;
}
//获取二叉搜索树的最大值
private int fetchMaxNodeVal(TreeNode node){
while(node.right != null){
node = node.right;
}
return node.val;
}
//获取二叉搜索树的最小值
private int fetchMinNodeVal(TreeNode node){
while(node.left != null){
node = node.left;
}
return node.val;
}
}