题目:有一棵二叉树,其中所有节点的值都不一样,找到含有节点最多 的搜索二叉子树,并返回这棵子树的头节点.
给定二叉树的头结点root,请返回所求的头结点,若出现多个节点最多的子树,返回头结点权值最大的。
Java代码:
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 {
public TreeNode getMax(TreeNode root) {
/*
以root为头的树,最大的搜索子树只能来自以下两种情况:
情况一:root为头的树整棵都是最大搜索二叉树,node左子树的最大搜索二叉树的最大值小于node节点值,node右子树的最大
搜索二叉树的最小值大于node节点值
情况二:不满足情况一,那么最大搜索二叉树的节点数就是node左子树上的最大搜索二叉树和node右子树上的最大搜索二叉树中
节点数较多的那个
1.整个过程是后序遍历
2.遍历到的当前节点为cur,先遍历cur的左子树并收集3个信息,分别是左子树上最大搜索二叉树的节点数,树上最大数,树上
最小数。再遍历cur的右子树同样记录3个值,节点数,树上最大数,树上最小数。
3.根据2收集的信息判断是否满足情况一,满足1的话就返回cur节点.否则满足情况2,返回左节点数和右节点数中较大的数的节点
*/
int[] record=new int[3];
return pos(root,record);
}
public TreeNode pos(TreeNode root,int[]record)
{
if(root==null)
{
record[0]=0;
record[1]=Integer.MIN_VALUE;
record[2]=Integer.MAX_VALUE;
return null;
}
TreeNode left=pos(root.left,record);
int lsize=record[0];//节点数
int lmax=record[1];//左子树上最大搜索二叉树的最大值
int lmin=record[2];//左子树上最大搜索二叉树的最小值
TreeNode right=pos(root.right,record);
int rsize=record[0];
int rmax=record[1];
int rmin=record[2];
if(left==root.left&&right==root.right)
{
if(left==null&&right==null)//左右子树为空的情况要考虑,不然结果为null
{
record[0]=1;
record[1]=root.val;
record[2]=root.val;
return root;
}
if(lmax<root.val&&rmin>root.val)
{
record[0]=lsize+rsize+1;
record[1]=Math.max(rmax,root.val);
record[2]=Math.min(lmin,root.val);
return root;
}
}
if(lsize>rsize||(lsize == rsize&& left.val >= right.val))//后一种为节点树相同时
{
record[0]=lsize;
record[1]=lmax;
record[2]=lmin;
return left;
}
else if(lsize < rsize || (lsize == rsize && left.val <right.val))
{
record[0]=rsize;
record[1]=rmax;
record[2]=rmin;
return right;
}
return root;
}
}
//另一种写法
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 {
public TreeNode getMax(TreeNode root) {
/*
以root为头的树,最大的搜索子树只能来自以下两种情况:
情况一:root为头的树整棵都是最大搜索二叉树,node左子树的最大搜索二叉树的最大值小于node节点值,node右子树的最大
搜索二叉树的最小值大于node节点值
情况二:不满足情况一,那么最大搜索二叉树的节点数就是node左子树上的最大搜索二叉树和node右子树上的最大搜索二叉树中
节点数较多的那个
1.整个过程是后序遍历
2.遍历到的当前节点为cur,先遍历cur的左子树并收集3个信息,分别是左子树上最大搜索二叉树的节点数,树上最大数,树上
最小数。再遍历cur的右子树同样记录3个值,节点数,树上最大数,树上最小数。
3.根据2收集的信息判断是否满足情况一,满足1的话就返回cur节点.否则满足情况2,返回左节点数和右节点数中较大的数的节点
*/
int[] record=new int[3];
return pos(root,record);
}
public TreeNode pos(TreeNode root,int[]record)
{
if(root==null)
{
record[0]=0;
record[1]=Integer.MIN_VALUE;
record[2]=Integer.MAX_VALUE;
return null;
}
TreeNode left=pos(root.left,record);
int lsize=record[0];//节点数
int lmax=record[1];//左子树上最大搜索二叉树的最大值
int lmin=record[2];//左子树上最大搜索二叉树的最小值
TreeNode right=pos(root.right,record);
int rsize=record[0];
int rmax=record[1];
int rmin=record[2];
record[1]=Math.max(rmax,root.val);
record[2]=Math.min(lmin,root.val);
if(left==root.left&&right==root.right&&lmax<root.val&&rmin>root.val)
{
record[0]=lsize+rsize+1;
return root;
}
record[0]=Math.max(lsize,rsize);
return lsize>rsize?left:right;
}
}