|
|
|
@ -48,154 +48,165 @@ public class Code05_MaxSubBSTSize {
|
|
|
|
|
return Math.max(maxSubBSTSize1(head.left), maxSubBSTSize1(head.right));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static int maxSubBSTSize2(Node head) {
|
|
|
|
|
if (head == null) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return process(head).maxSubBSTSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// public static Info process(Node head) {
|
|
|
|
|
// public static int maxSubBSTSize2(Node head) {
|
|
|
|
|
// if (head == null) {
|
|
|
|
|
// return 0;
|
|
|
|
|
// }
|
|
|
|
|
// return process(head).maxSubBSTSize;
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// // 任何子树
|
|
|
|
|
// public static class Info {
|
|
|
|
|
// public boolean isAllBST;
|
|
|
|
|
// public int maxSubBSTSize;
|
|
|
|
|
// public int min;
|
|
|
|
|
// public int max;
|
|
|
|
|
//
|
|
|
|
|
// public Info(boolean is, int size, int mi, int ma) {
|
|
|
|
|
// isAllBST = is;
|
|
|
|
|
// maxSubBSTSize = size;
|
|
|
|
|
// min = mi;
|
|
|
|
|
// max = ma;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// public static Info process(Node X) {
|
|
|
|
|
// if(X == null) {
|
|
|
|
|
// return null;
|
|
|
|
|
// }
|
|
|
|
|
// Info leftInfo = process(head.left);
|
|
|
|
|
// Info rightInfo = process(head.right);
|
|
|
|
|
// int min = head.value;
|
|
|
|
|
// int max = head.value;
|
|
|
|
|
// int maxSubBSTSize = 0;
|
|
|
|
|
// if (leftInfo != null) {
|
|
|
|
|
// Info leftInfo = process(X.left);
|
|
|
|
|
// Info rightInfo = process(X.right);
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// int min = X.value;
|
|
|
|
|
// int max = X.value;
|
|
|
|
|
//
|
|
|
|
|
// if(leftInfo != null) {
|
|
|
|
|
// min = Math.min(min, leftInfo.min);
|
|
|
|
|
// max = Math.max(max, leftInfo.max);
|
|
|
|
|
// maxSubBSTSize = Math.max(maxSubBSTSize, leftInfo.maxSubBSTSize);
|
|
|
|
|
// }
|
|
|
|
|
// if (rightInfo != null) {
|
|
|
|
|
// if(rightInfo != null) {
|
|
|
|
|
// min = Math.min(min, rightInfo.min);
|
|
|
|
|
// max = Math.max(max, rightInfo.max);
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// int maxSubBSTSize = 0;
|
|
|
|
|
// if(leftInfo != null) {
|
|
|
|
|
// maxSubBSTSize = leftInfo.maxSubBSTSize;
|
|
|
|
|
// }
|
|
|
|
|
// if(rightInfo !=null) {
|
|
|
|
|
// maxSubBSTSize = Math.max(maxSubBSTSize, rightInfo.maxSubBSTSize);
|
|
|
|
|
// }
|
|
|
|
|
// boolean isBST = false;
|
|
|
|
|
// if ((leftInfo == null ? true : (leftInfo.isAllBST && leftInfo.max < head.value))
|
|
|
|
|
// && (rightInfo == null ? true : (rightInfo.isAllBST && rightInfo.min > head.value))) {
|
|
|
|
|
// isBST = true;
|
|
|
|
|
// maxSubBSTSize = (leftInfo == null ? 0 : leftInfo.maxSubBSTSize)
|
|
|
|
|
// + (rightInfo == null ? 0 : rightInfo.maxSubBSTSize) + 1;
|
|
|
|
|
// boolean isAllBST = false;
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// if(
|
|
|
|
|
// // 左树整体需要是搜索二叉树
|
|
|
|
|
// ( leftInfo == null ? true : leftInfo.isAllBST )
|
|
|
|
|
// &&
|
|
|
|
|
// ( rightInfo == null ? true : rightInfo.isAllBST )
|
|
|
|
|
// &&
|
|
|
|
|
// // 左树最大值<x
|
|
|
|
|
// (leftInfo == null ? true : leftInfo.max < X.value)
|
|
|
|
|
// &&
|
|
|
|
|
// (rightInfo == null ? true : rightInfo.min > X.value)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// ) {
|
|
|
|
|
//
|
|
|
|
|
// maxSubBSTSize =
|
|
|
|
|
// (leftInfo == null ? 0 : leftInfo.maxSubBSTSize)
|
|
|
|
|
// +
|
|
|
|
|
// (rightInfo == null ? 0 : rightInfo.maxSubBSTSize)
|
|
|
|
|
// +
|
|
|
|
|
// 1;
|
|
|
|
|
// isAllBST = true;
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
// return new Info(isBST, maxSubBSTSize, min, max);
|
|
|
|
|
// return new Info(isAllBST, maxSubBSTSize, min, max);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 任何子树
|
|
|
|
|
|
|
|
|
|
public static int maxSubBSTSize2(Node head) {
|
|
|
|
|
if(head == null) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return process(head).maxBSTSubtreeSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class Info {
|
|
|
|
|
public boolean isAllBST;
|
|
|
|
|
public int maxSubBSTSize;
|
|
|
|
|
public int min;
|
|
|
|
|
public int maxBSTSubtreeSize;
|
|
|
|
|
public int allSize;
|
|
|
|
|
public int max;
|
|
|
|
|
public int min;
|
|
|
|
|
|
|
|
|
|
public Info(boolean is, int size, int mi, int ma) {
|
|
|
|
|
isAllBST = is;
|
|
|
|
|
maxSubBSTSize = size;
|
|
|
|
|
min = mi;
|
|
|
|
|
public Info(int m, int a, int ma, int mi) {
|
|
|
|
|
maxBSTSubtreeSize = m;
|
|
|
|
|
allSize = a;
|
|
|
|
|
max = ma;
|
|
|
|
|
min = mi;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Info process(Node X) {
|
|
|
|
|
if(X == null) {
|
|
|
|
|
|
|
|
|
|
public static Info process(Node x) {
|
|
|
|
|
if (x == null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
Info leftInfo = process(X.left);
|
|
|
|
|
Info rightInfo = process(X.right);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int min = X.value;
|
|
|
|
|
int max = X.value;
|
|
|
|
|
|
|
|
|
|
if(leftInfo != null) {
|
|
|
|
|
min = Math.min(min, leftInfo.min);
|
|
|
|
|
max = Math.max(max, leftInfo.max);
|
|
|
|
|
}
|
|
|
|
|
if(rightInfo != null) {
|
|
|
|
|
min = Math.min(min, rightInfo.min);
|
|
|
|
|
max = Math.max(max, rightInfo.max);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int maxSubBSTSize = 0;
|
|
|
|
|
if(leftInfo != null) {
|
|
|
|
|
maxSubBSTSize = leftInfo.maxSubBSTSize;
|
|
|
|
|
}
|
|
|
|
|
if(rightInfo !=null) {
|
|
|
|
|
maxSubBSTSize = Math.max(maxSubBSTSize, rightInfo.maxSubBSTSize);
|
|
|
|
|
}
|
|
|
|
|
boolean isAllBST = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(
|
|
|
|
|
// 左树整体需要是搜索二叉树
|
|
|
|
|
( leftInfo == null ? true : leftInfo.isAllBST )
|
|
|
|
|
&&
|
|
|
|
|
( rightInfo == null ? true : rightInfo.isAllBST )
|
|
|
|
|
&&
|
|
|
|
|
// 左树最大值<x
|
|
|
|
|
(leftInfo == null ? true : leftInfo.max < X.value)
|
|
|
|
|
&&
|
|
|
|
|
(rightInfo == null ? true : rightInfo.min > X.value)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
|
|
maxSubBSTSize =
|
|
|
|
|
(leftInfo == null ? 0 : leftInfo.maxSubBSTSize)
|
|
|
|
|
+
|
|
|
|
|
(rightInfo == null ? 0 : rightInfo.maxSubBSTSize)
|
|
|
|
|
+
|
|
|
|
|
1;
|
|
|
|
|
isAllBST = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return new Info(isAllBST, maxSubBSTSize, min, max);
|
|
|
|
|
Info leftInfo = process(x.left);
|
|
|
|
|
Info rightInfo = process(x.right);
|
|
|
|
|
int max = x.value;
|
|
|
|
|
int min = x.value;
|
|
|
|
|
int allSize = 1;
|
|
|
|
|
if (leftInfo != null) {
|
|
|
|
|
max = Math.max(leftInfo.max, max);
|
|
|
|
|
min = Math.min(leftInfo.min, min);
|
|
|
|
|
allSize += leftInfo.allSize;
|
|
|
|
|
}
|
|
|
|
|
if (rightInfo != null) {
|
|
|
|
|
max = Math.max(rightInfo.max, max);
|
|
|
|
|
min = Math.min(rightInfo.min, min);
|
|
|
|
|
allSize += rightInfo.allSize;
|
|
|
|
|
}
|
|
|
|
|
int p1 = -1;
|
|
|
|
|
if (leftInfo != null) {
|
|
|
|
|
p1 = leftInfo.maxBSTSubtreeSize;
|
|
|
|
|
}
|
|
|
|
|
int p2 = -1;
|
|
|
|
|
if (rightInfo != null) {
|
|
|
|
|
p2 = rightInfo.maxBSTSubtreeSize;
|
|
|
|
|
}
|
|
|
|
|
int p3 = -1;
|
|
|
|
|
boolean leftBST = leftInfo == null ? true : (leftInfo.maxBSTSubtreeSize == leftInfo.allSize);
|
|
|
|
|
boolean rightBST = rightInfo == null ? true : (rightInfo.maxBSTSubtreeSize == rightInfo.allSize);
|
|
|
|
|
if (leftBST && rightBST) {
|
|
|
|
|
boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < x.value);
|
|
|
|
|
boolean rightMinMoreX = rightInfo == null ? true : (x.value < rightInfo.min);
|
|
|
|
|
if (leftMaxLessX && rightMinMoreX) {
|
|
|
|
|
int leftSize = leftInfo == null ? 0 : leftInfo.allSize;
|
|
|
|
|
int rightSize = rightInfo == null ? 0 : rightInfo.allSize;
|
|
|
|
|
p3 = leftSize + rightSize + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return new Info(Math.max(p1, Math.max(p2, p3)), allSize, max, min);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// for test
|
|
|
|
|
public static Node generateRandomBST(int maxLevel, int maxValue) {
|
|
|
|
|