[面试题 04.05. 合法二叉搜索树](https://leetcode.cn/problems/legal-binary-search-tree-lcci/)
class TreeNode {
constructor(val, left = null, right = null) {
this.val = val;
this.left = left;
this.right = right;
}
}
var isValidBST = function (root) {
let stack = [];
let inorder = -Infinity;
while (stack.length || root) {
while (root) {
stack.push(root);
root = root.left;
}
root = stack.pop();
if (root.val <= inorder) return false;
inorder = root.val;
root = root.right;
}
return true;
};
// 构建测试用例
let root1 = new TreeNode(2, new TreeNode(1), new TreeNode(3));
console.log(isValidBST(root1)); // 输出: true
let root2 = new TreeNode(
5,
new TreeNode(1),
new TreeNode(4, new TreeNode(3), new TreeNode(6))
);
console.log(isValidBST(root2)); // 输出: false
这段代码实现了一个函数 isValidBST,用于判断一棵二叉树是否为有效的二叉搜索树(Binary Search Tree, BST)。下面是对代码的详细分析:
代码逻辑
-
初始化:
stack:一个栈,用于辅助中序遍历。inorder:记录上一次访问的节点值,初始值为负无穷大-Infinity。
-
外层循环:
- 条件是
stack.length || root,即只要栈不为空或者当前节点不为空,就继续执行。
- 条件是
-
内层循环:
- 将当前节点的所有左子节点依次入栈,直到到达最左边的节点。
- 这一步模拟了递归调用时不断深入到左子树的过程。
-
处理中间节点:
- 弹出栈顶元素,即当前子树中最左边的节点。
- 检查该节点的值是否大于
inorder。如果不是,则说明不是有效的二叉搜索树,返回false。 - 更新
inorder为当前节点的值。 - 处理完当前节点后,转向其右子节点,开始对右子树进行同样的操作。
-
返回结果:
- 如果整个遍历过程中没有发现违反二叉搜索树性质的情况,则返回
true。
- 如果整个遍历过程中没有发现违反二叉搜索树性质的情况,则返回
时间复杂度
- 由于每个节点都被访问一次,因此时间复杂度为 O(n),其中 n 是树中节点的数量。
空间复杂度
- 最坏情况下(当树退化成链表时),空间复杂度为 O(n)。平均情况下,空间复杂度为 O(h),其中 h 是树的高度。
示例
假设有一棵如下所示的二叉树:
2
/ \
1 3
调用 isValidBST(root) 将返回 true,因为这是一棵有效的二叉搜索树。
而如果树变为:
5
/ \
1 4
/ \
3 6
调用 isValidBST(root) 将返回 false,因为节点 4 的左子节点 3 不满足小于 4 的条件。
完整代码示例
为了更好地理解,这里提供一个完整的可运行的代码示例,包括构建二叉树和测试 isValidBST 函数的功能。
这个示例不仅包含了 isValidBST 函数的实现,还提供了如何构建二叉树以及如何测试该函数的方法。通过运行这些代码,可以验证 isValidBST 函数的正确性。

浙公网安备 33010602011771号