给定一个二叉树,判断它是否是合法的二叉查找树(BST)
一棵BST定义为:
- 节点的左子树中的值要严格小于该节点的值。
- 节点的右子树中的值要严格大于该节点的值。
- 左右子树也必须是二叉查找树。
- 一个节点的树也是二叉查找树。
- 样例
一个例子:
2 / \ 1 4 / \ 3 5
不可以,根据某种遍历方法,遍历所有的结点,检查是否满足结点node的值大于其左结点,小于其右结点。
与概念
- 节点的左子树中的值要严格小于该节点的值。
- 节点的右子树中的值要严格大于该节点的值。完全不同,比如图
- 解法一:
- 根据最基础的定义,我们在判断每棵子树的时候返回左子树的最大值小于当前节点值,同时右子树的最小值大于当前节点值,是的,这样会出现某些节点进行多次判断,当然我们可以通过添加数组结构来保存中间结果加快计算
- 代码:
class Solution {
public:
/**
* @param root: The root of binary tree.
* @return: True if the binary tree is BST, or false
*/
int maxright(TreeNode*root)
{
if(root==NULL)
return INT_MAX;
while(root->right)//不要写成while(root)两者有区别,如:分析{2,1}。
{
root=root->right;
}
return root->val;
}
int minleft(TreeNode*root)/同理,不要写成while(root)两者有区别,如:分析{2,#,1}。
{
if(root==NULL)
return INT_MIN;
while(root->left)
{
root=root->left;
}
return root->val;
}
bool isValidBST(TreeNode * root) {
// write your code here
if(root==NULL)
return true;
//若左子树的最大值大于等于其根值
if(root->left&&maxright(root->left)>=root->val)
return false;
//若右子树的最小值小于等于其根值
if(root->right&&minleft(root->right)<=root->val)
return false;
//递归
if(!isValidBST(root->left)|| !isValidBST(root->right))
return false;
return true;
}
};
方法二:根据二叉搜索树的中序遍历为递增的序列,可以先保存中序遍历的值,再判断其是否为递增序列
其中需要注意很多临界条件。
代码:
class Solution {
public:
/**
* @param root: The root of binary tree.
* @return: True if the binary tree is BST, or false
*/
void in(TreeNode*root,vector<int>&node)//注意一定要写&,不然bool函数中的node将为空
{ if(root==NULL)
return;//此判断语句必不可少
in(root->left,node);
node.push_back(root->val);
in(root->right,node);
}
bool isValidBST(TreeNode * root) {
// write your code here
if(root==NULL)
return true;//此判断语句必不可少
vector<int>node;
in(root,node);
for(int i=0;i<node.size()-1;i++)
{if(node[i]>=node[i+1])//注意二叉搜索树是结点值严格大于左子树的值、严格小于右子树的值
return false;}
return true;
}
};