第一题:
给定一棵二叉树的头节点head,请返回最大搜索二叉子树的大小
二叉树的套路
统一处理逻辑:假设以每个节点为头的这棵树,他的最大搜索二叉子树是什么。答案一定在其中
第一步,列出可能性(最难部分)
1、可能来自左子树上的某课子树
2、可能来自右子树上的某课子树
3、整颗都是(左右子树都是搜索二叉树并且左子树最大小于该节点,右子树最小大于该节点)
第二步,收集信息:
1、左树最大搜索子树大小
2、右树最大搜索子树大小
3、左树最大二叉搜索子树的头部(通过查看这个头部是否等于节点的左孩子,来判断整个左子树是否都是二叉搜索树)
4、右树最大二叉搜索子树的头部
5、左树最大值
6、右树最小值
化简为一个信息体:
1、左/右搜大小
2、左/右搜头
3、左max
4、右min
不管左树还是右树都存储
1、最大搜索子树大小
2、最大搜索子树的头部
3、这棵树上的最大值和最小值
如果不理解可以看引子题(很简单的)
一棵树中找最大最小
第三步,改递归(比较复杂)
先假设左和右都给我这样的信息了,然后怎么利用左边和右边的信息,组出来我该返回的信息。最后baseKey填什么,搞定!
public class Code_04_BiggestSubBSTInTree { public static class Node { public int value; public Node left; public Node right; public Node(int data) { this.value = data; } } public static Node biggestSubBST(Node head) { int[] record = new int[3]; // 0->size, 1->min, 2->max return posOrder(head, record); } 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)); } //数组实现版本 public static Node posOrder(Node head, int[] record) { if (head == null) { record[0] = 0; record[1] = Integer.MAX_VALUE; record[2] = Integer.MIN_VALUE; return null; } int value = head.value; Node left = head.left; Node right = head.right; Node lBST = posOrder(left, record); int lSize = record[0]; int lMin = record[1]; int lMax = record[2]; Node rBST = posOrder(right, record); int rSize = record[0]; int rMin = record[1]; int rMax = record[2]; record[1] = Math.min(rMin, Math.min(lMin, value)); // lmin, value, rmin -> min record[2] = Math.max(lMax, Math.max(rMax, value)); // lmax, value, rmax -> max if (left == lBST && right