题意理解
二叉搜索树的要求,每个节点大于其左子树中所有节点,且小于其右子树中所有节点。
方法一
前序遍历
对于每一个结点,我们判断它是否满足搜索树的条件,再依次判断其左孩子和右孩子是否满足。在判断节点是否满足条件时,分两种情况讨论:
1)该节点为左孩子,那么它要小于其父节点,且大于其父节点需要大于的值。
2)该节点为右孩子,那么它要大于其父节点,且小于其父节点需要小于的值。
换句话说,当父节点小于x时,以其为根的子树均小于x;当父节点大于y时,以其为根的子树均大于y。
下图展示了1、2对应的情形:
具体代码如下:
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return bool布尔型
*/
bool judge(TreeNode* root, int left, int right){
if (root == NULL) return true;
if (left<root->val && root->val < right)
return (judge(root->left, left, root->val) && judge(root->right, root->val, right));
return false;
}
bool isValidBST(TreeNode* root) {
// write code here
return judge(root, INT_MIN, INT_MAX);
}
};
时间复杂度: 。每一个节点都访问过一次。
空间复杂度: 。递归使用的栈的深度最多和节点数一样。
方法二
中序遍历
在二叉搜索树中,节点之间有前继和后继的关系,但是在本题输入中没有展现且在树中加入这层关系较为麻烦。我们考虑将二叉搜索树转换为数组形式,数字在数组中的前后顺序对应于二叉树中的前继后继关系,二叉搜索树对应的数组应该是递增的。我们使用中序遍历进行转换。
例如方法一中的案例转化为数组应为[a2,a3,a1,a5,a4,a6]。
具体代码如下:
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param root TreeNode类
* @return bool布尔型
*/
vector<int> num;
void midorder(TreeNode* root){
if (root == NULL) return;
midorder(root->left);
num.push_back(root->val);
midorder(root->right);
return;
}
bool isValidBST(TreeNode* root) {
// write code here
midorder(root);
//判断数组num是否递增
for (int i=1;i<num.size();i++)
if (num[i-1] > num[i])
return false;
return true;
}
};
时间复杂度: 。每一个节点都访问过一次,遍历一遍数组num。
空间复杂度: 。数组num的长度为节点个数N。