题面
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 严格小于 当前节点的数。
- 节点的右子树只包含 严格大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:

输入: root = [2,1,3] 输出: true
示例 2:

输入: root = [5,1,4,null,null,3,6] 输出: false 解释: 根节点的值是 5 ,但是右子节点的值是 4 。
提示:
- 树中节点数目范围在
[1, 104]内 -231 <= Node.val <= 231 - 1
分析
-
可以通过中序遍历,得到一个数组,然后判断该数组是否为升序的即可
/** * 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: bool isValidBST(TreeNode* root) { if (root == nullptr) return true; stack<TreeNode*> st; TreeNode* cur = root; vector<int> res; while (cur != nullptr || !st.empty()) { if (cur != nullptr) { st.push(cur); cur = cur->left; } else { cur = st.top(); st.pop(); res.push_back(cur->val); cur = cur->right; } } for (int i = 1; i < res.size(); i++) { if (res[i] <= res[i - 1]) return false; } return true; } }; -
实际上,可以直接将二叉树看作是一个数组,在遍历的过程中直接进行比较,这时需要记录一个 pre 表示根节点的值
class Solution { long long pre = LLONG_MIN; public: bool isValidBST(TreeNode* root) { if (root == nullptr) { return true; } if (!isValidBST(root->left)) { // 左 return false; } if (root->val <= pre) { // 中 return false; } pre = root->val; return isValidBST(root->right); // 右 } }; -
前序遍历:额外传入两个参数,分别表示从根到当前节点路径上的最小值和最大值,当前节点的值必须在最小值和最大值之间(不能等于)
class Solution { public: bool isValidBST(TreeNode* root, long long left = LLONG_MIN, long long right = LLONG_MAX) { if (root == nullptr) { return true; } long long x = root->val; return left < x && x < right && isValidBST(root->left, left, x) && isValidBST(root->right, x, right); } }; -
后序遍历:返回子树的最小值和最大值,供上面的节点判断是否为二叉搜索树
class Solution { pair<long long, long long> dfs(TreeNode* node) { if (node == nullptr) { return {LLONG_MAX, LLONG_MIN}; } auto[l_min, l_max] = dfs(node->left); auto[r_min, r_max] = dfs(node->right); long long x = node->val; // 也可以在递归完左子树之后立刻判断,如果发现不是二叉搜索树,就不用递归右子树了 if (x <= l_max || x >= r_min) { return {LLONG_MIN, LLONG_MAX}; } return {min(l_min, x), max(r_max, x)}; } public: bool isValidBST(TreeNode* root) { return dfs(root).second != LLONG_MAX; } };
这篇文档有帮助吗?