有一棵二叉树,其中所有节点的值都不一样,找到含有节点最多 的搜索二叉子树,并返回这棵子树的头节点.
给定二叉树的头结点root,请返回所求的头结点,若出现多个节点最多的子树,返回头结点权值最大的。
分析:
以节点node为头的树种,最大搜索二叉树只可能来自以下两种情况。
1.如果来自node左子树上的最大搜索二叉树是以node.left为头的;来自node右子树上的最大搜索二叉树是以node.right为头的;node左子树上的最大搜索二叉子树的最大值小于node.value;node右子树上的最大搜索二叉树的最小值大于node.value,那么以节点node为头的整个数都是搜索二叉树。
2.如果不满足第一种情况,说明一节点node为头的整棵树不能连城搜索二叉树。这种情况下,以node为头的树上的最大搜索二叉树来自node为头的树上的最大搜索二叉子树是来自node左子树上的最大搜索二叉树和来自node右子树上的最大二叉树子树中节点较多的那个。
3.整个过程后序遍历:遍历到当前节点即为cur,先遍历cur左子树收集四个信息,分别是左子树上最大搜索二叉树子头结点LBST,节点数LSize,最小值LMin和最大值LMax.再遍历cur右子树收集四个信息,分别是右子树上最大搜索二叉树子头结点RBST,节点数RSize,最小值RMin和最大值RMax
4.根据3中的信息,判断是否满足第一种情况,如果满足就返回cur,如果满足第二种就返回LBST和RBST中较大一个。
代码如下
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}*/
public class MaxSubtree {
private int nodeSize=0;
private int minVal=Integer.MAX_VALUE;
private int maxVal=Integer.MIN_VALUE;
public TreeNode getMax(TreeNode root) {
// write code here
return posOrder(root);
}
public TreeNode posOrder(TreeNode head){
if(head==null){
minVal=Integer.MAX_VALUE;
maxVal=Integer.MIN_VALUE;
nodeSize=0;
return null;
}
int value=head.val;
TreeNode left=head.left;
TreeNode right=head.right;
TreeNode lBST=posOrder(left);
int lNodeSize=nodeSize;
int lminVal=minVal;
int lmaxVal=maxVal;
TreeNode rBST=posOrder(right);
int rNodeSize=nodeSize;
int rminVal=minVal;
int rmaxVal=maxVal;
minVal=Math.min(value,lminVal);
maxVal=Math.max(value,rmaxVal);
if(left==lBST&&right==rBST&&lmaxVal<value&&rminVal>value){
nodeSize=lNodeSize+rNodeSize+1;
return head;
}
nodeSize=Math.max(lNodeSize,rNodeSize);
return lNodeSize>rNodeSize?lBST:rBST;
}
}