给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
利用“影子”二叉树
bool isValidBST(TreeNode* root) {
//“影子”二叉树 利用栈 每个节点对应一个范围
stack<pair<TreeNode *, pair<int64_t, int64_t>>>s;
pair<int64_t, int64_t> R{INT64_MIN,INT64_MAX};
while (root || !s.empty()) {
while (root) {
if (!(R.first < root->val && root->val < R.second)) {
return false;
}
s.push({root,R});
R.second = root->val;
root = root->left;
}
auto topNode = s.top();
s.pop();
root = topNode.first;
R = topNode.second;
R.first = root->val;
root = root->right;
}
return true;
}
void preOrder1(TreeNode *root, pair<int64_t, int64_t>r, bool &ans){
if (!root || !ans) {
return;
}
if (!(r.first < root->val && root->val < r.second)) {
ans = false;
return;
}
preOrder1(root->left,{r.first,root->val},ans);
preOrder1(root->right,{root->val,r.second},ans);
}
bool isValidBST(TreeNode* root) {
bool ans = true;
preOrder1(root,{INT64_MIN,INT64_MAX}, ans);
return ans;
}
002 中序遍历
class Solution {
void midOrder(TreeNode *root, bool &ans, int64_t &pre){
if (root && ans) {
midOrder(root->left, ans, pre);
// 中序遍历的时候节点的处理
// 利用前面结点的值pre来判断序列的有效性。
if (pre >= root->val) {
ans = false;
return;
}
pre = root->val;
midOrder(root->right, ans, pre);
}
}
public:
bool isValidBST(TreeNode* root) {
bool ans = true;
int64_t pre = INT64_MIN;
midOrder(root, ans, pre);
return ans;
}
};
003 后续遍历 拿到左右子树的区间
class Solution {
pair<int64_t, int64_t> postOrder(TreeNode *root, bool &ans) {
if (!root || !ans) {
return {INT64_MAX, INT64_MIN};
}
auto l = postOrder(root->left, ans);
auto r = postOrder(root->right, ans);
if (!(l.second < root->val && root->val < r.first)) {
ans = false;
return {INT64_MAX, INT64_MIN};
}
return {min<int64_t>(l.first, root->val), max<int64_t>(root->val, r.second)};
}
public:
bool isValidBST(TreeNode* root) {
bool ans = true;
postOrder(root, ans);
return ans;
}
};