题目:https://leetcode-cn.com/problems/validate-binary-search-tree/
思路一:中序遍历
-
中序遍历二叉树,将结点的值保存到一个数组里面;
-
判断数组里面的元素是不是按升序排列,是,就是二叉搜索树,不是,就返回false。
class Solution {
public:
vector<int> vec;
bool isValidBST(TreeNode* root) {
if(root==NULL)
return true;
vector<int>res=preinorder(root,vec);
for(int i=1;i<vec.size();i++)
{
if(vec[i]<=vec[i-1]) //判断是不是升序
return false;
}
return true;
}
vector<int> preinorder(TreeNode* root, vector<int> &vec)
{
if(root==NULL)
return vec;
preinorder(root->left, vec);
vec.push_back(root->val);
preinorder(root->right, vec);
return vec;
}
};
思路二;中序遍历优化
上述的方式会遍历所有的节点。中序遍历时;现在只需要找到一个节点比他们前面的节点大,就会返回返回false;不需要遍历所有的节点.(所以在单层遍历时假ruturn)。
难点:理解递归结束(return的使用)
-
如果根节点为空,就返回true
-
遍历左子树
-
如果遍历到的节点比前面的节点小,就返回false;
-
遍历右子树
-
返回 return left && right;(只要一个为零,结果就为零)
class Solution {
public:
TreeNode* pre = NULL; // 用来记录前一个节点
bool isValidBST(TreeNode* root)
{
if (root == NULL) return true;
bool left = isValidBST(root->left);
if (pre != NULL && pre->val >= root->val)
return false;
pre = root; // 记录前一个节点
bool right = isValidBST(root->right);
return left && right;
}
};
思路三:递归:
利用最大值最小值判定
设计一个递归函数 helper(root, lower, upper)判断,函数以root为根节点的树,判断节点的值是否在(l,r)里面,如果root结点的值不在里面,就就返回false,否者就继续调用递归函数;
根据二叉搜索树的性质,在递归日澳用左子树时,将upper改为 root-.val,即调用 helper(root.left, lower, root.val),因为左子树里所有节点的值均小于它的根节点的值。同理递归调用右子树时,我们需要把下界 lower 改为 root.val,即调用 helper(root.right, root.val, upper)。
class Solution{
bool helper(TreeNode* root, long long lower, long long upper)
{
if(root==NULL)
return true;
if(root->val<=lower||root->val>=upper)
return false;
return helper(root -> left, lower, root -> val) && helper(root -> right, root -> val, upper);
}
bool isValidBST(TreeNode* root) {
return helper(root, LONG_MIN, LONG_MAX);
}
}
思路四:栈
用栈模拟中序遍历
遍历左子树,节点入栈,由于栈先进后出,将左子树遍历结束后,抛出栈顶元素,和前一个节点进行比较,比前一个结点小,返回假,如果不是,则让当前节点成为前一个节点,看结点的右子树是否存在,存在,则入栈。
stack<TreeNode*>stk;
long long pre = LONG_MIN;
bool isValidBST(TreeNode* root)
{
if (root == NULL)
return true;
stk.push(root);
while (!stk.empty()|| root !=NULL)
{
while (root->left)
{
stk.push(root->left);
root = root->left;
}
root = stk.top();
stk.pop();
if (root->val <= pre)
return false;
pre =root->val;
if (root->right)
{
stk.push(root->right);
root = root->right;
}
}
return true;
}