「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」。
题目
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例1
输入:root = [2,1,3]
输出:true
示例2
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
思路
由于树结构的特殊性,遇到关于二叉树的题目,可以优先考虑递归方式求解
定义一个函数 checkNode(node, max, min)
,接受一个带校验的节点 node
,和一个上边界和下边界 max, min
;
为什么这么定义呢,根据题意,有效二叉搜索树:如果该二叉树的左子树不为空,则左子树的所有节点的值都小于该根节点;如果该二叉树的右子树不为空,则右子树的所有节点的值都大于该根节点的值;且左右子树都应该为有效的二叉搜索树,也就是左右子树也应该满足上述条件;
所以函数 checkNode
应该校验节点 root.val
应处于 min < root.val < max
中,如果不满足,则不是有效的二叉搜索树,否则继续校验该节点的左子树和右子树,直到校验完整棵树。
在函数启动时,由于传入的是根节点,则 max = Number.MAX_VALUE, min = -Number.MAX_VALUE
,因为任意根节点都是满足条件的;在校验左子树时,max = root.val
,因为左子树的上边界即为根节点,下边界不变;在校验右子树时,min = root.val
,因为右子树的下边界即为根节点,上边界不变;
递归完整代码如下
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isValidBST = function(root) {
const checkNode = (node, max, min) => {
// 节点不存在,符合题意
if(!node) {
return true;
}
// 节点不在范围内,不是有效二叉搜索树
if(node.val >= max || node.val <= min) {
return false;
}
// 再校验左右子树
return checkNode(node.left, node.val, min) && checkNode(node.right, max, node.val);
}
// 以 Number.MAX_VALUE, -Number.MAX_VALUE 启动校验函数
return checkNode(root, Number.MAX_VALUE, -Number.MAX_VALUE);
};
小结
二叉树的特点根明显,每个节点都是同样的结构,因此递归是比较好的思路
除夕快乐~(勿忘学习😂)
LeetCode 👉 HOT 100 👉 验证二叉搜索树 - 中等题 ✅
合集:LeetCode 👉 HOT 100,有空就会更新,大家多多支持,点个赞👍
如果大家有好的解法,或者发现本文理解不对的地方,欢迎留言评论 😄