题目描述:
给定一颗二叉树的头节点head,请返回最大搜索二叉树子树的大小。
搜索二叉树的大小:搜索二叉树的节点的个数。
思路分析:
1.分析可能性:
- 当前节点的左子树是搜索二叉树,而右节点并不是搜索二叉树;或者左节点的最大搜索二叉树的大小大于右节点的最大搜索二叉树的大小,那么此时最大的搜索二叉树就是它的左子树;
- 当前节点的右子树是搜索二叉树而左节点不是搜索二叉树;又或者左节点的最大搜索二叉树的大小小于右节点的最大搜索二叉树的大小,那么此时最大的搜索二叉树就是它的右子树;
- 当前节点的左子树和右子树都是搜索二叉树,并且当前节点的值大于左子树的最大搜索二叉树的最大值,小于右子树的最大搜索二叉树的最小值;此时,说明以当前节点为根节点的二叉树也是一颗搜索二叉树;
2 列信息全集:根据第一步的分析,我们可以得出,我们需要的信息有四个。
- 最大搜索二叉子树的头结点
- 最大搜索二叉子树的大小(最终需要返回的信息)
- 当前节点下最大搜索二叉树的最大值
- 当前节点下最大搜索二叉树的最小值
Java代码如下:
public class BiggestSubBSTInTree {
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static class ReturnType{
public int size;
public Node head;
public int min;
public int max;
public ReturnType(int a, Node b,int c,int d) {
this.size =a;
this.head = b;
this.min = c;
this.max = d;
}
}
public static ReturnType process(Node head) {
if(head == null) {
return new ReturnType(0,null,Integer.MAX_VALUE, Integer.MIN_VALUE);
}
Node left = head.left;
ReturnType leftSubTressInfo = process(left);
Node right = head.right;
ReturnType rightSubTressInfo = process(right);
int includeItSelf = 0;
if(leftSubTressInfo.head == left
&&rightSubTressInfo.head == right
&& head.value > leftSubTressInfo.max
&& head.value < rightSubTressInfo.min
) {
includeItSelf = leftSubTressInfo.size + 1 + rightSubTressInfo.size;
}
int p1 = leftSubTressInfo.size;
int p2 = rightSubTressInfo.size;
int maxSize = Math.max(Math.max(p1, p2), includeItSelf);
Node maxHead = p1 > p2 ? leftSubTressInfo.head : rightSubTressInfo.head;
if(maxSize == includeItSelf) {
maxHead = head;
}
return new ReturnType(maxSize,
maxHead,
Math.min(Math.min(leftSubTressInfo.min,rightSubTressInfo.min),head.value),
Math.max(Math.max(leftSubTressInfo.max,rightSubTressInfo.max),head.value));
}
}