需要注意的是这个题目并没有限定节点值的范围,而且没有限定每一个根节点都有左右子节点
最开始我想到了使用递归,每一次返回该节点是否是搜索二叉树、该节点以下的最大最小值,因为是使用左右子节点的情况进行分类,因此代码比较复杂
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
struct result{
int node_max;
int node_min;
bool isBST;
};
result * process(TreeNode *root)
{
if(root->left==NULL&&root->right==NULL)
{
result * re=new result;
re->node_min=root->val;
re->node_max=root->val;
re->isBST=true;
return re;
}
if(root->left!=NULL&&root->right!=NULL)
{
result * left=new result;
result * right=new result;
left=process(root->left);
right=process(root->right);
if(left->isBST&&right->isBST&&(left->node_max<root->val)&&(right->node_min>root->val))
{
result * re=new result;
re->node_min=left->node_min;
re->node_max=right->node_max;
re->isBST=true;
return re;
}
else{
result * re=new result;
re->node_min=left->node_min;
re->node_max=right->node_max;
re->isBST=false;
return re;
}
}
if(root->left!=NULL&&root->right==NULL)
{
result * left=new result;
left=process(root->left);
if(left->isBST&&(left->node_max<root->val))
{
result * re=new result;
re->node_min=left->node_min;
re->node_max=root->val;
re->isBST=true;
return re;
}
else{
result * re=new result;
re->node_min=left->node_min;
re->node_max=left->node_max;
re->isBST=false;
return re;
}
}
result * right=new result;
right=process(root->right);
if(right->isBST&&(right->node_min>root->val))
{
result * re=new result;
re->node_min=root->val;
re->node_max=right->node_max;
re->isBST=true;
return re;
}
else{
result * re=new result;
re->node_min=right->node_min;
re->node_max=right->node_max;
re->isBST=false;
return re;
}
}
bool isValidBST(TreeNode* root) {
result *re=new result;
re=process(root);
return re->isBST;
}
};
最简单的方法应该是中序遍历,在左神的课中就是用了这个版本,这个方法对二叉树进行中序遍历,每一次都将该节点的值与前一次进行比较(这里遍历在父节点的时候是父节点与左子树的最右节点比较,下一次就是右子树的最左节点与父子节点进行比较,省去了上面的去计算最大最小值的过程,而且base case中是对每个节点进行处理,而不是对左右节点进行处理,不用像上面那种分多钟情况)
直接上代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
long pre=LONG_MIN;
bool isValidBST(TreeNode* root) {
//base case
if(root==NULL)
return true;
//判断左子树
if(!isValidBST(root->left))
return false;
//判断值,在这里如果该节点是父节点,则是父节点和左子树最右节点比较,如果是右子树节点,就是右子树最左节点与父节点进行比较
if(root->val>pre)
pre=root->val;
else
return false;
//判断右子树
if(!isValidBST(root->right))
return false;
return true;
}
};
```javascript