题解 | #判断是不是二叉搜索树#

判断是不是二叉搜索树

http://www.nowcoder.com/practice/a69242b39baf45dea217815c7dedb52b

判断是不是二叉搜索树

题意

给定一个树,判断它是不是二叉搜索树

方法

转化成数组再比较

分析

一个树,是二叉搜索树,则它的中序遍历是递增数组

因此考虑通过先得到它的中序遍历,再判断数组内容是否有序

代码

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    void dfs(TreeNode* root, vector<int>& arr){
        if(root == NULL)return;
        dfs(root->left,arr);
        arr.push_back(root->val); // 中序遍历
        dfs(root->right,arr);
    }
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return bool布尔型
     */
    bool isValidBST(TreeNode* root) {
        vector<int> vals;
        dfs(root,vals);
        for(int i = 1;i < vals.size();i++){ // 判断是否有序
            if(vals[i] < vals[i-1])return false;
        }
        return true;
    }
};

复杂度分析

空间复杂度: 使用了数组来得到中序遍历,空间复杂度为O(n)O(n)

时间复杂度: 对于每个节点操作代价为常数,所以总时间复杂度为O(n)O(n)

遍历过程中比较

分析

如果一个树上每个节点和它左右子树相比较都合法,那么整个树合法

而对于一个节点只关心它左树的最大值和右树的最小值

考虑递归过程中,改造成返回一个树的最小值和最大值,而不是产生遍历

这样每个节点去检验,如果都满足则整个树合法

样例

以样例数据为例,

alt

代码

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 *	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 * };
 */
class Solution {
public:
    pair<int,int> dfs(TreeNode* root, bool & r){
        if(root == NULL)return {0,0};
        pair<int,int> ret = {root->val,root->val}; // 以当前节点为根的树的最小值和最大值
        if(root -> left){ // 左节点不为空
            auto lr = dfs(root->left,r);
            if(!r)return ret; // 失败提前返回
            if(lr.second >= root -> val) { // 左树最大值应该小于根节点
                r = false;
                return ret;
            }
            ret.first = lr.first; // 更新最小值
        }
        if(root -> right){ // 右节点不为空
            auto lr = dfs(root->right,r);
            if(!r)return ret; // 失败提前返回
            if(lr.first < root -> val) { // 右树最小值应该大于根节点
                r = false;
                return ret;
            }
            ret.second = lr.second; // 更新最大值
        }
        return ret;
    }
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return bool布尔型
     */
    bool isValidBST(TreeNode* root) {
        bool r = true; // 是否合法
        dfs(root,r);
        return r;
    }
};

复杂度分析

空间复杂度: 主要和递归深度相关,最坏情况树是链状,空间复杂度为O(n)O(n)

时间复杂度: 对于每个节点操作代价为常数,所以总时间复杂度为O(n)O(n)

全部评论

相关推荐

one_t:硕还是本?什么岗
点赞 评论 收藏
分享
头像
10-16 09:58
已编辑
门头沟学院 Java
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务