给定一棵二叉树的头节点head,已知其中所有节点的值都不一样,找到含有节点最多的搜索二叉树,并返回这颗子树的数量。
分析答案的可能性
- 第一种:X为头节点的子树中,最大的搜索二叉树就是X的左子树中的最大搜索二叉子树。即答案来自左子树
- 第二种:X为头节点的子树中,最大的搜索二叉树就是X的右子树中的最大搜索二叉子树。即答案来自右子树
- 第三种:若X左子树上的最大搜索二叉子树是X左子树的全体,X右子树上的最大搜索二叉子树是X右数全体,并且X的值大于X的左子树所有节点的最大值,且小于X右子树所有节点的最小值,那么X为头节点的子树中,最大的搜索二叉子树是以X为头节点的全体。
-
public static int largestBSTSubtree(TreeNode head) { if (head == null) { return 0; } return process(head).maxBSTSubtreeSize; } public static class Info { public int maxBSTSubtreeSize; public int allSize; public int max; public int min; public Info(int m, int a, int ma, int mi) { maxBSTSubtreeSize = m; allSize = a; max = ma; min = mi; } } public static Info process(TreeNode x) { if (x == null) { return null; } Info leftInfo = process(x.left); Info rightInfo = process(x.right); int max = x.val; int min = x.val; 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.val); boolean rightMinMoreX = rightInfo == null ? true : (x.val < 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); }