- 最大BST子树
思路
- 此题采用自底向上的思想,只有左右子树都为BST(包含null),那么其以root为根节点的二叉树才能是BST
- 这里想到后序遍历(左右根)
- 注意:有一种情况以root为根节点的二叉树不是BST,那么所求的BST一定在较矮的子树中,这里设置了 leftBSTSize = -1, rightBSTSize= -1,作为哨兵,如果root的左右子树都为BST(包含null),那么leftBSTSize, rightBSTSize 一定大于等于0
Solution
public class _333_最大BST子树 {
public int largeBSTSubtree(TreeNode root){
return (root == null) ? 0 : getInfo(root).size;
}
// 返回root为根节点的二叉树的最大BST子树信息
public Info getInfo(TreeNode root) {
if ( root == null ) return null;
// 左右子树信息
Info li = getInfo(root.left);
Info ri = getInfo(root.right);
/**
有4种情况,以root为根节点的二又树就是一棵BST,最大BST子树就是其本身
① li != null && ri != null
&& li.root == root.left && root.val > 1i.max
&& ri.root == root.right && root.val < ri.min
② li != nu1l && ri == nu11
&& 11.root == root.left && root.val > 1i.max
③ 1i == nu11 && ri != nu11
&& ri.root == root.right && root.val < ri.min
④ 1i == nu11 && ri == nu11
*/
int leftBSTSize = -1, rightBSTSize= -1 , max = root.val, min = root.val;
if (li == null){
leftBSTSize = 0;
}else if (li.root == root.left && li.max < root.val){
leftBSTSize = li.size;
min = li.min;
}
if (ri == null){ // 右子树为空
rightBSTSize = 0;
}else if (ri.root == root.right && ri.min > root.val){ // 右子树不为空,且满足根节点的第一个右节点就为BST
rightBSTSize = ri.size;
max = ri.max;
}
// 以root为根的二叉树是BST
if (leftBSTSize != -1 && rightBSTSize != -1){
return new Info(root,1+li.size+ri.size,max,min)
}
// 均不为-1,即左右子树存在,但以root作为根的二叉树不是BST
// BST可能就是在较矮的子树中
if(li!=null && ri != null) return (li.size > ri.size) ? li :ri;
// 返回li、ri中不为null的那个Info
return (li!= null) ? li:ri;
}
private static class Info {
public TreeNode root;
public int size;
public int max;
public int min;
public Info(TreeNode root, int size, int max, int min){
this.root =root;
this.size =size;
this.max = max;
this.min = min;
}
}
}
Reference:小码哥MJ