给定一棵二叉树的头节点head,
返回这颗二叉树中最大的二叉搜索子树的大小
方法1:
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static int 最大的二叉搜索子树的大小(Node head) {
if (head == null) {
return 0;
}
return process(head).maxBinarySearchSize;
}
public static class Info {
private int minVal;
private int maxVal;
private int maxBinarySearchSize;
private boolean isBinarySearch;
public Info(int min, int max, int mbss, boolean ibss) {
minVal = min;
maxVal = max;
maxBinarySearchSize = mbss;
isBinarySearch = ibss;
}
}
public static Info process(Node x) {
if (x == null) {
return null;
}
Info leftInfo = process(x.left);
Info rightInfo = process(x.right);
int minVal = x.value;
int maxVal = x.value;
int maxBinarySearchSize = 1;
boolean isBinarySearch = true;
if (leftInfo != null) {
minVal = Math.min(minVal, leftInfo.minVal);
maxVal = Math.max(maxVal, leftInfo.maxVal);
isBinarySearch = isBinarySearch && leftInfo.isBinarySearch;
if (leftInfo.maxVal >= x.value) {
isBinarySearch = false;
}
}
if (rightInfo != null) {
minVal = Math.min(minVal, rightInfo.minVal);
maxVal = Math.max(maxVal, rightInfo.maxVal);
isBinarySearch = isBinarySearch && rightInfo.isBinarySearch;
if (rightInfo.minVal <= x.value) {
isBinarySearch = false;
}
}
if ((leftInfo != null && rightInfo != null)) {
if (leftInfo.isBinarySearch && rightInfo.isBinarySearch && leftInfo.maxVal < x.value && rightInfo.minVal > x.value) {
//如果左右子树都存在
//如果当前节点左右子树都是BST,并且当前节点的树和左右子树也符合BST
//那么最大BST大小是 左+右+1
maxBinarySearchSize = leftInfo.maxBinarySearchSize + rightInfo.maxBinarySearchSize + 1;
} else {
//如果左或右子树不是BST 或者 当前节点的树和左右节点不符合BST
//那么最大BST大小是 左右子树中较大BST的大小
maxBinarySearchSize = Math.max(leftInfo.maxBinarySearchSize, rightInfo.maxBinarySearchSize);
}
}
if (leftInfo != null && rightInfo == null) {
if (leftInfo.isBinarySearch && leftInfo.maxVal < x.value) {
//如果只有左子树 右子树为空
//并且左子树是BST, 当前节点的树跟左子树也符合BST
//那么最大BST大小是 左子树最大BST大小+1
maxBinarySearchSize = leftInfo.maxBinarySearchSize + 1;
} else {
//如果左子树不是BST 或者 当前节点的树和左子树不符合BST
//那么最大BST大小是 左子树最大BST大小
maxBinarySearchSize = leftInfo.maxBinarySearchSize;
}
}
if (leftInfo == null && rightInfo != null) {
if (rightInfo.isBinarySearch && rightInfo.minVal > x.value) {
maxBinarySearchSize = rightInfo.maxBinarySearchSize + 1;
} else {
maxBinarySearchSize = rightInfo.maxBinarySearchSize;
}
}
return new Info(minVal, maxVal, maxBinarySearchSize, isBinarySearch);
}
方法2:
tips : 二叉搜索树中序遍历的结果是升序
public static int getBSTSize(Node head) {
ArrayList<Node> arr = new ArrayList<Node>();
in(head, arr);
int size = arr.size();
for (int i = 1; i < arr.size(); i++) {
if (arr.get(i).value <= arr.get(i - 1).value){
return 0;
}
}
return size;
}
public static void in(Node head, ArrayList<Node> arr) {
if (head == null) {
return;
}
in(head.left, arr);
arr.add(head);
in(head.right, arr);
}
public static int maxSubBSTSize1(Node head) {
if (head == null) {
return 0;
}
int bstSize = getBSTSize(head);
if (bstSize != 0){
return bstSize;
}
return Math.max(maxSubBSTSize1(head.left),maxSubBSTSize1(head.right));
}