二叉树
平衡二叉树进阶
题目:给定一棵二叉树的头节点head,判断该树是否是平衡二叉树
根据标准想可能性,这一步是自己根据题意分析的。
给定一棵二叉树的头节点head,判断该树是否是平衡二叉树。
如果这棵树为平衡二叉树,那么它的子树也必为平衡二叉树
判断子树的情况需要两个参数,一个是子树深度size,一个是子树是否平衡根据支持可能心需要什么信息 收集信息 所有需要的信息做一个类型一次返回
- 先默认左右子树都能返回节点类型的信息
- 收集信息+决策过程
- 写了哪些信息需要返回,然后再加上自己这个当前节点向上返回,遇到base case跳出
public class IsBalancedTree {
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static boolean isBalance(Node head) {
boolean[] res = new boolean[1];
res[0] = true;
getHeight(head, 1, res);
return res[0];
}
/*
1.根据标准想可能性,这一步是自己根据题意分析的。
给定一棵二叉树的头节点head,判断该树是否是平衡二叉树。
如果这棵树为平衡二叉树,那么它的子树也必为平衡二叉树
判断子树的情况需要两个参数,一个是子树深度size,一个是子树是否平衡
*/
/*
2.根据支持可能心需要什么信息 收集信息 所有需要的信息做一个类型一次返回
*/
public static class ReturnType {
public int level;
public boolean isB;
public ReturnType(int l, boolean is) {
level = l;
isB = is;
}
}
// process(head, 1)
public static boolean m(Node head){
return process(head, 1).isB;
/*
3.先默认左右子树都能返回节点类型的信息
*/
public static ReturnType process(Node head, int level) {
if (head == null) {//base case。空树认为是平衡二叉树
return new ReturnType(level, true);
}
ReturnType leftSubTreeInfo = process(head.left, level + 1);
/*
4.收集信息
*/
if(!leftSubTreeInfo.isB) {//左树不平衡 返回false 现在level没有意义
return new ReturnType(level, false);
}
ReturnType rightSubTreeInfo = process(head.right, level + 1);
if(!rightSubTreeInfo.isB) {//右树不平衡 返回false
return new ReturnType(level, false);
}
//前面两步都没返回,说明左右子树都平衡
//现在看左右子树高度差是否超过1
if (Math.abs(rightSubTreeInfo.level - leftSubTreeInfo.level) > 1) {
return new ReturnType(level, false);
}
/*
4.收集信息+决策过程
*/
//树的深度取左右子树深的那一个
return new ReturnType(Math.max(leftSubTreeInfo.level, rightSubTreeInfo.level), true);
/*
5.写了哪些信息需要返回,然后再加上自己这个当前节点向上返回
*/
}
public static int getHeight(Node head, int level, boolean[] res) {
if (head == null) {
return level;
}
int lH = getHeight(head.left, level + 1, res);
if (!res[0]) {
return level;
}
int rH = getHeight(head.right, level + 1, res);
if (!res[0]) {
return level;
}
if (Math.abs(lH - rH) > 1) {
res[0] = false;
}
return Math.max(lH, rH);
}
public static void main(String[] args) {
Node head = new Node(1);
head.left = new Node(2);
head.right = new Node(3);
head.left.left = new Node(4);
head.left.right = new Node(5);
head.right.left = new Node(6);
head.right.right = new Node(7);
System.out.println(isBalance(head));
}
}
二叉搜索树进阶
题目:给定一棵二叉树的头节点head,已知所有节点的值都不一样,求最大的搜索二叉子树的节点数量。
/*
1.根据标准想可能性
可能性1 最大搜索二叉树在左树上
可能性2 最大搜索二叉树在右树上
可能性3 最大搜索二叉树是根节点所在的整棵树
2.支持可能性所需要的信息
左树上最大搜索二叉树的size
右树上最大搜索二叉树的size
子树上最大搜索二叉树的头部,不是树的头部
这棵树的最大值和最小值
其实只需要左树的最大值和右树的最小值,但是每个递归过程都是一样的
所以我们搜集信息的时候要全部收集,然后让上级决策
3.默认左右子树都能返回如上的信息
4.拿到收集的信息,如何组合出可能性1、2、3
5.写了哪些信息需要返回,加上当前节点的信息,组合好,向上返回,遇到base case跳出
*/
public class 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;//左树上最大搜索二叉树的size。不是左树的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 == rBST && lMax < value && value < rMin) {
record[0] = lSize + rSize + 1;
return head;
}
record[0] = Math.max(lSize, rSize);
return lSize > rSize ? lBST : rBST;
}
// for test -- print tree
public static void printTree(Node head) {
System.out.println("Binary Tree:");
printInOrder(head, 0, "H", 17);
System.out.println();
}
public static void printInOrder(Node head, int height, String to, int len) {
if (head == null) {
return;
}
printInOrder(head.right, height + 1, "v", len);
String val = to + head.value + to;
int lenM = val.length();
int lenL = (len - lenM) / 2;
int lenR = len - lenM - lenL;
val = getSpace(lenL) + val + getSpace(lenR);
System.out.println(getSpace(height * len) + val);
printInOrder(head.left, height + 1, "^", len);
}
public static String getSpace(int num) {
String space = " ";
StringBuffer buf = new StringBuffer("");
for (int i = 0; i < num; i++) {
buf.append(space);
}
return buf.toString();
}
public static void main(String[] args) {
Node head = new Node(6);
head.left = new Node(1);
head.left.left = new Node(0);
head.left.right = new Node(3);
head.right = new Node(12);
head.right.left = new Node(10);
head.right.left.left = new Node(4);
head.right.left.left.left = new Node(2);
head.right.left.left.right = new Node(5);
head.right.left.right = new Node(14);
head.right.left.right.left = new Node(11);
head.right.left.right.right = new Node(15);
head.right.right = new Node(13);
head.right.right.left = new Node(20);
head.right.right.right = new Node(16);
printTree(head);
Node bst = biggestSubBST(head);
printTree(bst);
}
}