1. import java.util.ArrayList;
    2. /**
    3. * 题目1. 返回一个树中子树为二叉搜索树的最大节点数
    4. * 和题目2一个类型的题目
    5. * 题目2. 给定一棵二叉树的头节点,返回这棵二叉树中最大的二叉搜索子树的头节点
    6. */
    7. public class Code05_MaxSubBSTSize {
    8. public static class Node {
    9. public int value;
    10. public Node left;
    11. public Node right;
    12. public Node(int data) {
    13. this.value = data;
    14. }
    15. }
    16. public static int getBSTSize(Node head) {
    17. if (head == null) {
    18. return 0;
    19. }
    20. ArrayList<Node> arr = new ArrayList<>();
    21. in(head, arr);
    22. for (int i = 1; i < arr.size(); i++) {
    23. if (arr.get(i).value <= arr.get(i - 1).value) {
    24. return 0;
    25. }
    26. }
    27. return arr.size();
    28. }
    29. public static void in(Node head, ArrayList<Node> arr) {
    30. if (head == null) {
    31. return;
    32. }
    33. in(head.left, arr);
    34. arr.add(head);
    35. in(head.right, arr);
    36. }
    37. public static int maxSubBSTSize1(Node head) {
    38. if (head == null) {
    39. return 0;
    40. }
    41. int h = getBSTSize(head);
    42. if (h != 0) {
    43. return h;
    44. }
    45. return Math.max(maxSubBSTSize1(head.left), maxSubBSTSize1(head.right));
    46. }
    47. // public static int maxSubBSTSize2(Node head) {
    48. // if (head == null) {
    49. // return 0;
    50. // }
    51. // return process(head).maxSubBSTSize;
    52. // }
    53. //
    54. //
    55. //
    56. //
    57. //
    58. //
    59. //
    60. //
    61. //
    62. // // 任何子树
    63. // public static class Info {
    64. // public boolean isAllBST;
    65. // public int maxSubBSTSize;
    66. // public int min;
    67. // public int max;
    68. //
    69. // public Info(boolean is, int size, int mi, int ma) {
    70. // isAllBST = is;
    71. // maxSubBSTSize = size;
    72. // min = mi;
    73. // max = ma;
    74. // }
    75. // }
    76. //
    77. //
    78. //
    79. //
    80. // public static Info process(Node X) {
    81. // if(X == null) {
    82. // return null;
    83. // }
    84. // Info leftInfo = process(X.left);
    85. // Info rightInfo = process(X.right);
    86. //
    87. //
    88. //
    89. // int min = X.value;
    90. // int max = X.value;
    91. //
    92. // if(leftInfo != null) {
    93. // min = Math.min(min, leftInfo.min);
    94. // max = Math.max(max, leftInfo.max);
    95. // }
    96. // if(rightInfo != null) {
    97. // min = Math.min(min, rightInfo.min);
    98. // max = Math.max(max, rightInfo.max);
    99. // }
    100. //
    101. //
    102. //
    103. //
    104. //
    105. //
    106. //
    107. // int maxSubBSTSize = 0;
    108. // if(leftInfo != null) {
    109. // maxSubBSTSize = leftInfo.maxSubBSTSize;
    110. // }
    111. // if(rightInfo !=null) {
    112. // maxSubBSTSize = Math.max(maxSubBSTSize, rightInfo.maxSubBSTSize);
    113. // }
    114. // boolean isAllBST = false;
    115. //
    116. //
    117. // if(
    118. // // 左树整体需要是搜索二叉树
    119. // ( leftInfo == null ? true : leftInfo.isAllBST )
    120. // &&
    121. // ( rightInfo == null ? true : rightInfo.isAllBST )
    122. // &&
    123. // // 左树最大值<x
    124. // (leftInfo == null ? true : leftInfo.max < X.value)
    125. // &&
    126. // (rightInfo == null ? true : rightInfo.min > X.value)
    127. //
    128. //
    129. // ) {
    130. //
    131. // maxSubBSTSize =
    132. // (leftInfo == null ? 0 : leftInfo.maxSubBSTSize)
    133. // +
    134. // (rightInfo == null ? 0 : rightInfo.maxSubBSTSize)
    135. // +
    136. // 1;
    137. // isAllBST = true;
    138. //
    139. //
    140. // }
    141. // return new Info(isAllBST, maxSubBSTSize, min, max);
    142. // }
    143. public static int maxSubBSTSize2(Node head) {
    144. if(head == null) {
    145. return 0;
    146. }
    147. return process(head).maxBSTSubtreeSize;
    148. }
    149. public static class Info {
    150. public int maxBSTSubtreeSize;// 最大搜索字数的节点的个数
    151. public int allSize; // 整棵树的节点个数
    152. public int max; // 最大值
    153. public int min; // 最小值
    154. public Info(int m, int a, int ma, int mi) {
    155. maxBSTSubtreeSize = m;
    156. allSize = a;
    157. max = ma;
    158. min = mi;
    159. }
    160. }
    161. // 递归
    162. public static Info process(Node x) {
    163. // base case 不好设置,x为空时,最大值最小值不好设置,返回为空,交给上层处理
    164. if (x == null) {
    165. return null;
    166. }
    167. Info leftInfo = process(x.left);
    168. Info rightInfo = process(x.right);
    169. // 加工自己的信息属性
    170. int max = x.value; // 最大值和最小值暂时设置为value
    171. int min = x.value;
    172. int allSize = 1;
    173. if (leftInfo != null) {
    174. max = Math.max(leftInfo.max, max);
    175. min = Math.min(leftInfo.min, min);
    176. allSize += leftInfo.allSize;
    177. }
    178. if (rightInfo != null) {
    179. max = Math.max(rightInfo.max, max);
    180. min = Math.min(rightInfo.min, min);
    181. allSize += rightInfo.allSize;
    182. }
    183. // 可能性1
    184. int p1 = -1;
    185. if (leftInfo != null) {
    186. p1 = leftInfo.maxBSTSubtreeSize;
    187. }
    188. // 可能性2 p2表示2可能情况下的maxSize,最大BST的节点个数
    189. int p2 = -1;
    190. if (rightInfo != null) {
    191. p2 = rightInfo.maxBSTSubtreeSize;
    192. }
    193. // 可能性3 x作为最大BST的头节点 null节点默认为搜索二叉树
    194. int p3 = -1;
    195. boolean leftBST = leftInfo == null ? true : (leftInfo.maxBSTSubtreeSize == leftInfo.allSize); //
    196. boolean rightBST = rightInfo == null ? true : (rightInfo.maxBSTSubtreeSize == rightInfo.allSize);
    197. if (leftBST && rightBST) { // 左树整体是BST并且右侧整体是BST
    198. boolean leftMaxLessX = leftInfo == null ? true : (leftInfo.max < x.value);
    199. boolean rightMinMoreX = rightInfo == null ? true : (x.value < rightInfo.min);
    200. if (leftMaxLessX && rightMinMoreX) { // 左树最大值 < x 并且右树最小值 > x
    201. int leftSize = leftInfo == null ? 0 : leftInfo.allSize;
    202. int rightSize = rightInfo == null ? 0 : rightInfo.allSize;
    203. p3 = leftSize + rightSize + 1; // maxSize
    204. }
    205. }
    206. // 最后比较求最大的maxSize
    207. int maxBSTSubtreeSize = Math.max(p1, Math.max(p2, p3));
    208. return new Info(maxBSTSubtreeSize, allSize, max, min);
    209. }
    210. // for test
    211. public static Node generateRandomBST(int maxLevel, int maxValue) {
    212. return generate(1, maxLevel, maxValue);
    213. }
    214. // for test
    215. public static Node generate(int level, int maxLevel, int maxValue) {
    216. if (level > maxLevel || Math.random() < 0.5) {
    217. return null;
    218. }
    219. Node head = new Node((int) (Math.random() * maxValue));
    220. head.left = generate(level + 1, maxLevel, maxValue);
    221. head.right = generate(level + 1, maxLevel, maxValue);
    222. return head;
    223. }
    224. public static void main(String[] args) {
    225. int maxLevel = 4;
    226. int maxValue = 100;
    227. int testTimes = 1000000;
    228. for (int i = 0; i < testTimes; i++) {
    229. Node head = generateRandomBST(maxLevel, maxValue);
    230. if (maxSubBSTSize1(head) != maxSubBSTSize2(head)) {
    231. System.out.println("Oops!");
    232. }
    233. }
    234. System.out.println("finish!");
    235. }
    236. }