思想上的提醒,极度模板化代码
1、给定一颗二叉树的头结点head,返回这颗二叉树是不是平衡二叉树
平衡二叉树:在一棵二叉树中,每一颗子树左树的最大高度和右数的最大高度相差的绝对值不超过1
public static boolean isCBT1(Node head) {if (head == null) {return true;}LinkedList<Node> queue = new LinkedList<>();// 是否遇到过左右两个孩子不双全的节点boolean leaf = false;Node l = null;Node r = null;queue.add(head);while (!queue.isEmpty()) {head = queue.poll();l = head.left;r = head.right;if (// 如果遇到了不双全的节点之后,又发现当前节点不是叶节点(leaf && (l != null || r != null))||(l == null && r != null)) {return false;}if (l != null) {queue.add(l);}if (r != null) {queue.add(r);}if (l == null || r == null) {leaf = true;}}return true;}
public static boolean isCBT2(Node head) {if (head == null) {return true;}return process(head).isCBT;}private static Info process(Node head) {if (head == null) {return new Info(true, 0);}Info leftInfo = process(head.left);Info rightInfo = process(head.right);int highDiff = Math.abs(leftInfo.high - rightInfo.high);boolean isCBT = leftInfo.isCBT && rightInfo.isCBT && highDiff < 2;return new Info(isCBT, Math.max(leftInfo.high, rightInfo.high) + 1);}private static class Info {//是否平衡二叉树boolean isCBT;//高度int high;public Info(boolean isCBT, int high) {this.isCBT = isCBT;this.high = high;}}
2、如何判断一棵树是不是搜索二叉树
搜索二叉树:每一颗子树中,子树左边的值都比头小,子树右边的值都比头大 经典的搜索二叉树 没有重复值,如果需要处理重复值,则采用在相同值的节点内使用链表
public static boolean isBST1(Node head) {if (head == null) {return true;}ArrayList<Node> arr = new ArrayList<>();in(head, arr);for (int i = 1; i < arr.size(); i++) {if (arr.get(i).value <= arr.get(i - 1).value) {return false;}}return true;}public static void in(Node head, ArrayList<Node> arr) {if (head == null) {return;}in(head.left, arr);arr.add(head);in(head.right, arr);}
public static boolean isBST2(Node head) {if (head == null) {return true;}return process(head).isBST;}public static class Info {//是否搜索二叉树public boolean isBST;//左树中的最大值public int max;//右树中的最小值public int min;public Info(boolean i, int ma, int mi) {isBST = i;max = ma;min = mi;}}public static Info process(Node x) {if (x == null) {return null;}Info leftInfo = process(x.left);Info rightInfo = process(x.right);int max = x.value;if (leftInfo != null) {max = Math.max(max, leftInfo.max);}if (rightInfo != null) {max = Math.max(max, rightInfo.max);}int min = x.value;if (leftInfo != null) {min = Math.min(min, leftInfo.min);}if (rightInfo != null) {min = Math.min(min, rightInfo.min);}boolean isBST = true;if (leftInfo != null && !leftInfo.isBST) {isBST = false;}if (rightInfo != null && !rightInfo.isBST) {isBST = false;}if (leftInfo != null && leftInfo.max >= x.value) {isBST = false;}if (rightInfo != null && rightInfo.min <= x.value) {isBST = false;}return new Info(isBST, max, min);}
给定一颗二叉树的头结点head,任何两个节点之间的都存在距离,返回整颗二叉树的最大距离
public static int maxDistance2(Node head) {return process(head).maxDistance;}public static class Info {//子树最大距离public int maxDistance;//子树高度public int height;public Info(int m, int h) {maxDistance = m;height = h;}}public static Info process(Node x) {if (x == null) {return new Info(0, 0);}Info leftInfo = process(x.left);Info rightInfo = process(x.right);int height = Math.max(leftInfo.height, rightInfo.height) + 1;int p1 = leftInfo.maxDistance;int p2 = rightInfo.maxDistance;int p3 = leftInfo.height + rightInfo.height + 1;int maxDistance = Math.max(Math.max(p1, p2), p3);return new Info(maxDistance, height);}
判断一颗数是否是满二叉树
满二叉树:如果一课数的高度为h,则该树的节点数为2h-1
// 第一种方法// 收集整棵树的高度h,和节点数n// 只有满二叉树满足 : 2 ^ h - 1 == npublic static boolean isFull1(Node head) {if (head == null) {return true;}Info1 all = process1(head);return (1 << all.height) - 1 == all.nodes;}public static class Info1 {public int height;public int nodes;public Info1(int h, int n) {height = h;nodes = n;}}public static Info1 process1(Node head) {if (head == null) {return new Info1(0, 0);}Info1 leftInfo = process1(head.left);Info1 rightInfo = process1(head.right);int height = Math.max(leftInfo.height, rightInfo.height) + 1;int nodes = leftInfo.nodes + rightInfo.nodes + 1;return new Info1(height, nodes);}
// 第二种方法// 收集子树是否是满二叉树// 收集子树的高度// 左树满 && 右树满 && 左右树高度一样 -> 整棵树是满的public static boolean isFull2(Node head) {if (head == null) {return true;}return process2(head).isFull;}public static class Info2 {public boolean isFull;public int height;public Info2(boolean f, int h) {isFull = f;height = h;}}public static Info2 process2(Node h) {if (h == null) {return new Info2(true, 0);}Info2 leftInfo = process2(h.left);Info2 rightInfo = process2(h.right);boolean isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height;int height = Math.max(leftInfo.height, rightInfo.height) + 1;return new Info2(isFull, height);}
给定一颗二叉树的头结点,返回这颗二叉树中最大的二叉搜索子树的头结点
public static Node maxSubBSTHead2(Node head) {if (head == null) {return null;}return process(head).maxSubBSTHead;}// 每一棵子树public static class Info {//最大搜索子树的头结点public Node maxSubBSTHead;//最大搜索子树的节点数public int maxSubBSTSize;//右树的最小值public int min;//左树的最大值public int max;public Info(Node h, int size, int mi, int ma) {maxSubBSTHead = h;maxSubBSTSize = size;min = mi;max = ma;}}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;Node maxSubBSTHead = null;int maxSubBSTSize = 0;if (leftInfo != null) {min = Math.min(min, leftInfo.min);max = Math.max(max, leftInfo.max);maxSubBSTHead = leftInfo.maxSubBSTHead;maxSubBSTSize = leftInfo.maxSubBSTSize;}if (rightInfo != null) {min = Math.min(min, rightInfo.min);max = Math.max(max, rightInfo.max);if (rightInfo.maxSubBSTSize > maxSubBSTSize) {maxSubBSTHead = rightInfo.maxSubBSTHead;maxSubBSTSize = rightInfo.maxSubBSTSize;}}if ((leftInfo == null ? true : (leftInfo.maxSubBSTHead == X.left && leftInfo.max < X.value))&& (rightInfo == null ? true : (rightInfo.maxSubBSTHead == X.right && rightInfo.min > X.value))) {maxSubBSTHead = X;maxSubBSTSize = (leftInfo == null ? 0 : leftInfo.maxSubBSTSize)+ (rightInfo == null ? 0 : rightInfo.maxSubBSTSize) + 1;}return new Info(maxSubBSTHead, maxSubBSTSize, min, max);}
