【前端面试常见算法题系列】98. 验证二叉搜索树(中等)

267 阅读1分钟

“Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。”

一、题目描述

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。  

示例 1: image.png

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

示例 2: image.png

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4

提示:

  • 树中节点数目范围在 [1, 104]
  • -231 <= Node.val <= 231 - 1

二、思路分析

判断 root 是不是一棵二叉搜索树,有一个点需要注意,那就是对于节点值的大小判断。

初学者做这题很容易有误区:BST 不是左小右大么,那我只要检查 root.val > root.left.val 且 root.val < root.right.val 不就行了?

其实这样是不对的,因为 BST 左小右大的特性是指 root.val 要比左子树的所有节点都更大,要比右子树的所有节点都小,你只检查左右两个子节点当然是不够的。

正确解法是通过使用辅助函数,增加函数参数列表,在参数中携带额外信息,将这种约束传递给子树的所有节点。这样一来,这道题就可以解出来了。

三、AC 代码

/**
 * 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 isValidBST(root, nullptr, nullptr);
    }
    bool isValidBST(TreeNode* root, TreeNode* min, TreeNode* max) {
        // base case
        if (!root) return true;

        // 查看左子树
        if (max && root -> val >= max -> val) return false;
        // 查看右子树
        if (min && root -> val <= min -> val) return false;
        // 限定左子树的最大值是 root.val,右子树的最小值是 root.val
        return isValidBST(root -> left, min, root) && isValidBST(root -> right, root, max);
    }
};