leetcode验证二叉搜索树

题目:

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

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

这是leetcode里面我遇到的一道比较有意思的题目,题目的意思非常清楚:输入一棵树,判断它是不是二叉搜索树。大家对二叉搜索树的概念应该非常熟悉,题目中也非常清楚地给出了判定二叉搜索树的几个条件(应该说是充分必要条件),看到这三个条件:节点的左子树只包含小于当前节点的数、节点的右子树只包含大于当前节点的数、所有左子树和右子树自身必须也是二叉搜索树,第一反应肯定是想到使用递归来做,也应该是一道比较简单的题目。

当我仔细去思考如何去构造递归过程的时候发现这道题其实并没有我想象得那么容易,当判断判断节点的左子树只包含小于当前节点的数与节点的右子树只包含大于当前节点的数这两个条件时,需要分别知道左子树的最大值右子树的最小值,但是仅仅知道这两个值还是不够的,当前节点作为子树节点在递归回溯的过程中还需要知道该节点下面所有节点中的最大值和最小值,因此在递归的过程中还是需要知道该节点的左子树的最小值右子树的最大值

如果用l_min、l_max、r_min、r_max分别表示该节点的左子树中的最小值、左子树中的最大值、右子树中的最小值、右子树中的最大值,在递归返回的过程中,如果该节点的左子树和右子树满足条件进一步推断该节点也是一颗二叉搜索树,每个节点的左子树的最小值和右子树的最大值就会成为该节点为根的子树中的最小值和最大值,这一点时递归过程中的关键

代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isValidBST(TreeNode* root) {
        int a,b;
        return isvalid(root,a,b);
    }
private:
    bool isvalid(TreeNode* root,int &max,int &min)//max传出root下最大值、min传出root下最小值
    {
        if(root==NULL)
        {
            //初始化当前节点中的最大值和最小值
            max=INT_MIN;
            min=INT_MAX;
            return true;
        }
        int left_max,left_min,right_max,right_min;//左子树的最大值、左子树的最小值、右子树的最大值、右子树的最小值
        
        //递归判断左子树和右子树是否是二叉搜索树,并通过引用分别传出左子树和右子树的最大值和最小值
        if(isvalid(root->left,left_max,left_min)&&isvalid(root->right,right_max,right_min))
        {
            //分为四种情况
            
            //右子树为空、左子树不为空
            if(root->left==NULL&&root->right!=NULL)
            {
                if(root->val<right_min)
                {
                    min=root->val;//传出最小值和最大值
                    max=right_max;
                    return true;
                }
                else
                    return false;
            }
            //右子树位空、左子树不为空
            if(root->right==NULL&&root->left!=NULL)
            {
                if(root->val>left_max)
                {
                    min=left_min;
                    max=root->val;
                    return true;
                }
                else
                    return false;
            }
            //左子树、右子树都为空
            if(root->left==NULL&&root->right==NULL)
            {
                min=root->val;
                max=root->val;
                return true;
            }
            //左子树、右子树都不为空
            if(root->val>left_max&&root->val<right_min)
            {
                min=left_min;
                max=right_max;
                return true;
            }
            else
                return false;
        }
        else
            return false;
    }
};

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值