题目:
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 严格小于 当前节点的数。
- 节点的右子树只包含 严格大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
思路:
什么是二叉搜索树?
就是每个节点的左子节点的值小于当前节点值,每个右子节点的值大于当前节点的值
我们有三种方式来实现
- 前序
- 中序
- 后续
前序
先判断,再递归
利用边界来进行判断
中序
遍历一个,判断一下是否大于上一个节点的值
注意: 中序遍历二叉搜索树,得到的遍历结果是递增的
后续
代码:
前序:
var isValidBST = function (root) {
function dfs(root, left , right ) {
if(!root)return true;
let x = root.val;
let leftVal = dfs(root.left,left,x);
let rightVal = dfs(root.right,x,right);
return left < x && x < right && leftVal && rightVal;
}
return dfs(root,-Infinity,Infinity);
};
中序:
var isValidBST = function (root) {
let prev = -Infinity;
function dfs(node) {
if (!node) return true;
let left = dfs(node.left);
if (!left) return false;
if (node.val <= prev) {
return false;
}
prev = node.val;
let right = dfs(node.right);
return right;
}
return dfs(root);
};
后续:
感觉后续最麻烦
var isValidBST = function (root) {
// 返回 [min, max] 或 null (如果不合法)
function dfs(node) {
if (!node) return [Infinity, -Infinity];
const left = dfs(node.left);
const right = dfs(node.right);
// 如果左右子树有任何一个不合法(返回了 null),直接向上冒泡
if (left === null || right === null) return null;
const [leftMin, leftMax] = left;
const [rightMin, rightMax] = right;
// 检查当前节点是否合法
if (leftMax >= node.val || rightMin <= node.val) {
return null;
}
return [Math.min(node.val, leftMin), Math.max(node.val, rightMax)];
}
return dfs(root) !== null;
};