333最大BST子树

给定一个二叉树,找到其中最大的二叉搜索树(BST)子树,并返回该子树的大小。其中,最大指的是子树节点数最多的。

二叉搜索树(BST)中的所有节点都具备以下属性:

左子树的值小于其父(根)节点的值。

右子树的值大于其父(根)节点的值。

注意:

子树必须包含其所有后代。
进阶:

你能想出 O(n) 时间复杂度的解法吗?

示例:
333最大BST子树
输入:root = [10,5,15,1,8,null,7]
输出:3
解释:本例中最大的 BST 子树是高亮显示的子树。返回值是子树的大小,即 3 。
1.遍历

class Solution {
public:
    bool valid(TreeNode* root,int l,int r){
        if(root==NULL) return 1;
        if(root->val<=l||root->val>=r) return 0;
        return valid(root->left,l,root->val)&&valid(root->right,root->val,r);
    }
    int cnt(TreeNode* root) {
        return root?cnt(root->left)+cnt(root->right)+1:0;
    }
    int largestBSTSubtree(TreeNode* root) {
        if(root==NULL) return 0;
        if(valid(root,INT_MIN,INT_MAX)) return cnt(root);
        return max(largestBSTSubtree(root->left),largestBSTSubtree(root->right));
    }
};

我们枚举每个节点需要 O(n)的时间,而检查每个节点为根的子树是不是二叉搜索树需要 O(n)的时间,所以一共需要 O(n^2) 的时间复杂度
2.复用子树信息


struct Node{
    int l,r,sz;
};
class Solution{
    int ans=0;
public:
    int largestBSTSubtree(TreeNode* root){
        if(root==NULL) return 0;
        dfs(root);
        return ans;
    }
    Node dfs(TreeNode* root){
        if(root->left==NULL&&root->right==NULL) {
            ans = max(ans,1);
            return (Node){root->val,root->val,1};
        }
        int sz=1;
        bool valid=true;
        int l=root->val,r=root->val;
        if(root->left!=NULL) {
            Node L = dfs(root->left);
            if(L.sz!=-1&&root->val>L.r) {
                sz+=L.sz;
                l=L.l;
            }else valid=false;
        }
        if(root->right!=NULL){
            Node R = dfs(root->right);
            if(R.sz!=-1&&root->val<R.l){
                sz+=R.sz;
                r=R.r;
            }else valid=false;
        }
        if(valid) {
            ans=max(ans,sz);
            return (Node){l,r,sz};
        }
        return (Node){-1,-1,-1};
    }
};
上一篇:二叉搜索树2


下一篇:二叉搜索树1