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;
}