【力扣-二叉树】16、验证二叉搜索树(98)

179 阅读2分钟

「这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战

98. 验证二叉搜索树

题目描述

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

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

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

示例 1:

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

示例 2:

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

解析

使用中序遍历,将节点的值存入到数组中。再判断数组是否是递增的(且不含重复元素),递增则说明是二叉搜索树,否则就不是。

  • 二叉树的特点:
    • 左子树的节点值都小于当前节点值
    • 右子树的节点值都大于当前节点值

递归法

// 中序遍历
// 使用数组存储节点的值,如果节点的值是有序递增的,则说明是二叉搜索树
class Solution
{
public:
    bool isValidBST(TreeNode *root)
    {
        vec.clear();
        traversal(root);
        // 二叉搜索树中没有重复的节点
        for (int i = 1; i < vec.size(); i++)
        {
            if (vec[i] <= vec[i - 1])
            {
                return false;
            }
        }

        return true;
    }

private:
    vector<int> vec;
    // 将二叉搜索树的节点存入到数组中
    void traversal(TreeNode *node)
    {
        if (node == NULL)
        {
            return;
        }
        // 左
        traversal(node->left);
        // 中
        vec.push_back(node->val);
        // 右
        traversal(node->right);
    }
};

迭代法

class Solution
{
public:
    bool isValidBST(TreeNode *root)
    {
        if (root == NULL)
        {
            return false;
        }

        // 中序遍历存放节点
        stack<TreeNode *> st;
        // 当前遍历的节点
        TreeNode *cur = root;
        // 记录前一个节点
        TreeNode *pre = NULL;
        while (cur != NULL || !st.empty())
        {
            if (cur != NULL)
            {
                st.push(cur);

                // 左
                cur = cur->left;
            }
            else
            {
                cur = st.top();
                st.pop();

                if (pre != NULL && cur->val <= pre->val)
                {
                    return false;
                }
                // 保存前一个访问的节点
                pre = cur;

                // 右
                cur = cur->right;
            }
        }
        return true;
    }
};