题目LeetCode98
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含严格小于当前节点的数。
- 节点的右子树只包含 严格大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树
示例
**输入:**root = [2,1,3]
**输出:**true
Python解法
解法一(递归)
python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
# 辅助函数:检查以node为根的子树是否在(low, high)这个区间内
def check(node, must_greater_than, must_less_than):
# 情况1:节点是空的,说明这条路径没问题,返回True
if not node:
return True
# 情况2:节点不满足"必须大于左边的数"
if must_greater_than is not None and node.val <= must_greater_than:
return False
# 情况3:节点不满足"必须小于右边的数"
if must_less_than is not None and node.val >= must_less_than:
return False
# 检查左子树:
# 左子树所有节点都必须 < 当前节点值
# 同时左子树所有节点都要继承"必须大于的数"
left_ok = check(node.left, must_greater_than, node.val)
# 检查右子树:
# 右子树所有节点都必须 > 当前节点值
# 同时右子树所有节点都要继承"必须小于的数"
right_ok = check(node.right, node.val, must_less_than)
# 左右都没问题,整棵子树才是合法的
return left_ok and right_ok
# 根节点一开始没有任何限制:
# 没有"必须大于谁",也没有"必须小于谁"
return check(root, None, None)
解法二(中序遍历)
python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
stack = []
prev = float('-inf') # 记录中序遍历的前一个节点值
# 中序遍历的标准迭代写法:左-根-右
while stack or root:
# 1. 一路往左走,把所有左节点压入栈
while root:
stack.append(root)
root = root.left
# 2. 取出栈顶节点(此时是当前最左未访问的节点)
root = stack.pop()
# 3. 核心判断:当前节点值必须严格大于前一个节点值
if root.val <= prev:
return False
prev = root.val # 更新前一个节点值为当前值
# 4. 转向右子树(下一轮继续处理右子树的左分支)
root = root.right
return True
过程展示

Java解法
解法一(递归)
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
return check(root, null, null);
}
/**
* @param node 当前要检查的节点
* @param mustGreaterThan 当前节点必须大于这个值(可以为 null,表示无下限)
* @param mustLessThan 当前节点必须小于这个值(可以为 null,表示无上限)
*/
private boolean check(TreeNode node, Integer mustGreaterThan, Integer mustLessThan) {
// 空节点默认合法
if (node == null) {
return true;
}
// 不满足下限限制
if (mustGreaterThan != null && node.val <= mustGreaterThan) {
return false;
}
// 不满足上限限制
if (mustLessThan != null && node.val >= mustLessThan) {
return false;
}
// 左子树:上限变成当前节点值,下限继承
boolean leftOk = check(node.left, mustGreaterThan, node.val);
// 右子树:下限变成当前节点值,上限继承
boolean rightOk = check(node.right, node.val, mustLessThan);
return leftOk && rightOk;
}
}
解法二(中序遍历)
java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
long prev = Long.MIN_VALUE; // 用 long 避免 int 边界溢出
while (!stack.isEmpty() || root != null) {
// 一路向左走,全部入栈
while (root != null) {
stack.push(root);
root = root.left;
}
// 弹出节点
root = stack.pop();
// 核心判断:必须严格递增
if (root.val <= prev) {
return false;
}
prev = root.val;
// 走向右子树
root = root.right;
}
return true;
}
}
C++解法
解法一(递归)
cpp
/**
* 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) {
return check(root, nullptr, nullptr);
}
private:
/**
* @param node 当前节点
* @param mustGreaterThan 当前节点必须大于这个值(可以为 nullptr,表示无下限)
* @param mustLessThan 当前节点必须小于这个值(可以为 nullptr,表示无上限)
*/
bool check(TreeNode* node, int* mustGreaterThan, int* mustLessThan) {
if (!node) {
return true;
}
// 不满足下限限制
if (mustGreaterThan != nullptr && node->val <= *mustGreaterThan) {
return false;
}
// 不满足上限限制
if (mustLessThan != nullptr && node->val >= *mustLessThan) {
return false;
}
// 左子树:上限变成当前节点值,下限继承
bool leftOk = check(node->left, mustGreaterThan, &(node->val));
// 右子树:下限变成当前节点值,上限继承
bool rightOk = check(node->right, &(node->val), mustLessThan);
return leftOk && rightOk;
}
};
解法二(中序遍历)
cpp
/**
* 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) {
stack<TreeNode*> stack;
long prev = LONG_MIN; // 避免 int 边界问题
while (!stack.empty() || root != nullptr) {
// 一路向左走,全部入栈
while (root != nullptr) {
stack.push(root);
root = root->left;
}
// 弹出节点
root = stack.top();
stack.pop();
// 核心判断
if (root->val <= prev) {
return false;
}
prev = root->val;
// 走向右子树
root = root->right;
}
return true;
}
};