题目:
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入: 2 / \ 1 3 输出: true
示例 2:
输入: 5 / \ 1 4 / \ 3 6 输出: false 解释: 输入为: [5,1,4,null,null,3,6]。 根节点的值为 5 ,但是其右子节点值为 4 。
起初按照题目定义写出代码如下:
class Solution {
public:
bool isValidBST(TreeNode* root) {
if(root!=NULL){
int flag = 0;
BST_dfs(root,flag);
if(flag)
return false;
else
return true;
}
else
return true;
}
void BST_dfs(TreeNode* root,int &flag){
if(root->left==NULL&&root->right==NULL)
return;
if(root->left!=NULL){
if(root->val < root->left->val){
flag = 1;
return;
}
BST_dfs(root->left,flag);
}
if(root->right!=NULL){
if(root->val > root->right->val){
flag = 1;
return;
}
BST_dfs(root->right,flag);
}
}
};
这种写法忽略了如下情况:那就是6本应在二叉树的左子树却在右子树,但是上述代码每次只能判断一个节点和他左右两个节点是否满足要求;后面,看评论说二叉搜索树的中序遍历为递增,因此可利用这一方法进行判断。代码改写如下:
10 / \ 5 15 / \ 6 20
struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x):val(x),left(NULL),right(NULL){}
};
class Solution{
public:
bool isValidBST(TreeNode* root){
vector<int> ch;
if(root==NULL) return true;
else{
order_BST(root,ch);
if(ch.size()==1)
return true;
for(int i=0;i<ch.size()-1;i++){
if(ch[i]>=ch[i+1])
return false;
}
return true;
}
}
void order_BST(TreeNode* root, vector<int>& vec){
if(!root)
return;
order_BST(root->left,vec);
vec.push_back(root->val);
order_BST(root->right,vec);
}
};