int max = 0;
public int largestBSTSubtree(TreeNode root) {
if (root == null) {
return max;
}
helper(root);
return max;
}
private ResultType helper(TreeNode root) {
if (root == null) {
// return size = 0, -infinity, +infinity - so that we can return the leaf value up
return new ResultType(0, Integer.MAX_VALUE, Integer.MIN_VALUE);
}
ResultType left = helper(root.left);
ResultType right = helper(root.right);
// -1 means invalid BST, so we stop adding the nodes up if either subtree is not BST
// if root's value is smaller than high of left || bigger than low of right
// means it's not a BST, return -1 up
if (left.size == -1 || right.size == -1 || root.val <= left.hight || root.val >= right.low) {
return new ResultType(-1, 0, 0);// doesn't matter what the bound is for non BST
}
// if we are here means, both left & right & current node is valid BST, add them up
int curSize = left.size + right.size + 1;
max = Math.max(max, curSize); // update global max
// return the size, and min
return new ResultType(curSize, Math.min(left.low, root.val), Math.max(right.hight, root.val));
}
}
class ResultType {
int size; // size of this subtree
int low; // the lower bound that's valid
int hight; // the upper bound that's valid
public ResultType(int s, int l, int h) {
size = s;
low = l;
hight = h;
}
}