LeetCode 333. Largest BST Subtree

Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest means subtree with largest number of nodes in it.

Note:
A subtree must include all of its descendants.
Here’s an example:

    10
    / \
   5  15
  / \   \ 
 1   8   7

The Largest BST Subtree in this case is the highlighted one. (5-1-8)
The return value is the subtree’s size, which is 3.

Hint:

You can recursively use algorithm similar to 98. Validate Binary Search Tree at each node of the tree, which will result in O(nlogn) time complexity.
Follow up:
Can you figure out ways to solve it with O(n) time complexity?

s思路:
1. 树的问题,首先看是否遍历。遍历到每个leaf,可以默认是size=1的bst;其他node,如果两个孩子都是bst或者空(null可以认为是size=0的bst),且node->val大于左孩子,小于右孩子,就可以update node为bst,且总个数为左右之和;如果左右孩子有一个是bst或两个都是bst,但是node的值不满足bst的条件,只需要把最大数目传递上去,然后表明不是bst。
2. 上面的方法还有问题,参考http://www.cnblogs.com/grandyang/p/5188938.html 判断是否bst,应该是node->val>=左子树的最大值,<=右子树的最小值。不能只是和node->left->val以及node->right->val比较!!
3. 强化一下bst判断条件:root大于左子树最大值,小于右子树最小值!

//方法1:用count代表两个信息:符号代表是否bst,大小代表bst的节点数。注意:负数代表这个节点不是bst的根节点,但其某个子节点或孙子节点是bst,且节点数即使这个负数的绝对值!
int largestBSTSubtree(TreeNode* root) {
    int minv=INT_MIN,maxv=INT_MAX;
    int count=dfs(root,minv,maxv);
    return abs(count);
}

int dfs(TreeNode* root,int&minv,int&maxv){
    if(!root) {
        return 0;
    }
    int minv_l=INT_MIN,minv_r=INT_MAX;
    int maxv_l=INT_MIN,maxv_r=INT_MAX;
    int left=dfs(root->left,minv_l,maxv_l);
    int right=dfs(root->right,minv_r,maxv_r);
    if(left>=0&&right>=0){
        if((root->left&&root->val>=maxv_l||!root->left)&&(root->right&&root->val<=minv_r||!root->right)){
            minv=root->left?minv_l:root->val;
            maxv=root->right?maxv_r:root->val;
            return 1+left+right;
        }           
        return -max(left,right);
    }else
        return -max(abs(left),abs(right));
}


//方法2:count是非负数,用bool表示是否bst。和方法1比,复杂一些,变量也多一些!
int largestBSTSubtree(TreeNode* root) {
    int minv=INT_MIN,maxv=INT_MAX;
    int count=0;
    dfs(root,minv,maxv,count);
    return count;
}

bool dfs(TreeNode* root,int&minv,int&maxv,int&count){
    if(!root) return false;
    int minv_l=INT_MIN,minv_r=INT_MAX;
    int maxv_l=INT_MIN,maxv_r=INT_MAX;
    int count_l=0,count_r=0;
    int left=dfs(root->left,minv_l,maxv_l,count_l);
    int right=dfs(root->right,minv_r,maxv_r,count_r);
    if(left&&right){
        if((root->left&&root->val>=maxv_l||!root->left)&&(root->right&&root->val<=minv_r||!root->right)){
            minv=root->left?minv_l:root->val;
            maxv=root->right?maxv_r:root->val;
            count=1+left+right;
            return true;
        }           
    }
    count=max(count_l,count_r);
    return false;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值