思想上的提醒,极度模板化代码

1、给定一颗二叉树的头结点head,返回这颗二叉树是不是平衡二叉树

平衡二叉树:在一棵二叉树中,每一颗子树左树的最大高度和右数的最大高度相差的绝对值不超过1

  1. public static boolean isCBT1(Node head) {
  2. if (head == null) {
  3. return true;
  4. }
  5. LinkedList<Node> queue = new LinkedList<>();
  6. // 是否遇到过左右两个孩子不双全的节点
  7. boolean leaf = false;
  8. Node l = null;
  9. Node r = null;
  10. queue.add(head);
  11. while (!queue.isEmpty()) {
  12. head = queue.poll();
  13. l = head.left;
  14. r = head.right;
  15. if (
  16. // 如果遇到了不双全的节点之后,又发现当前节点不是叶节点
  17. (leaf && (l != null || r != null))
  18. ||
  19. (l == null && r != null)
  20. ) {
  21. return false;
  22. }
  23. if (l != null) {
  24. queue.add(l);
  25. }
  26. if (r != null) {
  27. queue.add(r);
  28. }
  29. if (l == null || r == null) {
  30. leaf = true;
  31. }
  32. }
  33. return true;
  34. }
  1. public static boolean isCBT2(Node head) {
  2. if (head == null) {
  3. return true;
  4. }
  5. return process(head).isCBT;
  6. }
  7. private static Info process(Node head) {
  8. if (head == null) {
  9. return new Info(true, 0);
  10. }
  11. Info leftInfo = process(head.left);
  12. Info rightInfo = process(head.right);
  13. int highDiff = Math.abs(leftInfo.high - rightInfo.high);
  14. boolean isCBT = leftInfo.isCBT && rightInfo.isCBT && highDiff < 2;
  15. return new Info(isCBT, Math.max(leftInfo.high, rightInfo.high) + 1);
  16. }
  17. private static class Info {
  18. //是否平衡二叉树
  19. boolean isCBT;
  20. //高度
  21. int high;
  22. public Info(boolean isCBT, int high) {
  23. this.isCBT = isCBT;
  24. this.high = high;
  25. }
  26. }

2、如何判断一棵树是不是搜索二叉树

搜索二叉树:每一颗子树中,子树左边的值都比头小,子树右边的值都比头大 经典的搜索二叉树 没有重复值,如果需要处理重复值,则采用在相同值的节点内使用链表

  1. public static boolean isBST1(Node head) {
  2. if (head == null) {
  3. return true;
  4. }
  5. ArrayList<Node> arr = new ArrayList<>();
  6. in(head, arr);
  7. for (int i = 1; i < arr.size(); i++) {
  8. if (arr.get(i).value <= arr.get(i - 1).value) {
  9. return false;
  10. }
  11. }
  12. return true;
  13. }
  14. public static void in(Node head, ArrayList<Node> arr) {
  15. if (head == null) {
  16. return;
  17. }
  18. in(head.left, arr);
  19. arr.add(head);
  20. in(head.right, arr);
  21. }
  1. public static boolean isBST2(Node head) {
  2. if (head == null) {
  3. return true;
  4. }
  5. return process(head).isBST;
  6. }
  7. public static class Info {
  8. //是否搜索二叉树
  9. public boolean isBST;
  10. //左树中的最大值
  11. public int max;
  12. //右树中的最小值
  13. public int min;
  14. public Info(boolean i, int ma, int mi) {
  15. isBST = i;
  16. max = ma;
  17. min = mi;
  18. }
  19. }
  20. public static Info process(Node x) {
  21. if (x == null) {
  22. return null;
  23. }
  24. Info leftInfo = process(x.left);
  25. Info rightInfo = process(x.right);
  26. int max = x.value;
  27. if (leftInfo != null) {
  28. max = Math.max(max, leftInfo.max);
  29. }
  30. if (rightInfo != null) {
  31. max = Math.max(max, rightInfo.max);
  32. }
  33. int min = x.value;
  34. if (leftInfo != null) {
  35. min = Math.min(min, leftInfo.min);
  36. }
  37. if (rightInfo != null) {
  38. min = Math.min(min, rightInfo.min);
  39. }
  40. boolean isBST = true;
  41. if (leftInfo != null && !leftInfo.isBST) {
  42. isBST = false;
  43. }
  44. if (rightInfo != null && !rightInfo.isBST) {
  45. isBST = false;
  46. }
  47. if (leftInfo != null && leftInfo.max >= x.value) {
  48. isBST = false;
  49. }
  50. if (rightInfo != null && rightInfo.min <= x.value) {
  51. isBST = false;
  52. }
  53. return new Info(isBST, max, min);
  54. }

给定一颗二叉树的头结点head,任何两个节点之间的都存在距离,返回整颗二叉树的最大距离

  1. public static int maxDistance2(Node head) {
  2. return process(head).maxDistance;
  3. }
  4. public static class Info {
  5. //子树最大距离
  6. public int maxDistance;
  7. //子树高度
  8. public int height;
  9. public Info(int m, int h) {
  10. maxDistance = m;
  11. height = h;
  12. }
  13. }
  14. public static Info process(Node x) {
  15. if (x == null) {
  16. return new Info(0, 0);
  17. }
  18. Info leftInfo = process(x.left);
  19. Info rightInfo = process(x.right);
  20. int height = Math.max(leftInfo.height, rightInfo.height) + 1;
  21. int p1 = leftInfo.maxDistance;
  22. int p2 = rightInfo.maxDistance;
  23. int p3 = leftInfo.height + rightInfo.height + 1;
  24. int maxDistance = Math.max(Math.max(p1, p2), p3);
  25. return new Info(maxDistance, height);
  26. }

判断一颗数是否是满二叉树

满二叉树:如果一课数的高度为h,则该树的节点数为2h-1

  1. // 第一种方法
  2. // 收集整棵树的高度h,和节点数n
  3. // 只有满二叉树满足 : 2 ^ h - 1 == n
  4. public static boolean isFull1(Node head) {
  5. if (head == null) {
  6. return true;
  7. }
  8. Info1 all = process1(head);
  9. return (1 << all.height) - 1 == all.nodes;
  10. }
  11. public static class Info1 {
  12. public int height;
  13. public int nodes;
  14. public Info1(int h, int n) {
  15. height = h;
  16. nodes = n;
  17. }
  18. }
  19. public static Info1 process1(Node head) {
  20. if (head == null) {
  21. return new Info1(0, 0);
  22. }
  23. Info1 leftInfo = process1(head.left);
  24. Info1 rightInfo = process1(head.right);
  25. int height = Math.max(leftInfo.height, rightInfo.height) + 1;
  26. int nodes = leftInfo.nodes + rightInfo.nodes + 1;
  27. return new Info1(height, nodes);
  28. }
  1. // 第二种方法
  2. // 收集子树是否是满二叉树
  3. // 收集子树的高度
  4. // 左树满 && 右树满 && 左右树高度一样 -> 整棵树是满的
  5. public static boolean isFull2(Node head) {
  6. if (head == null) {
  7. return true;
  8. }
  9. return process2(head).isFull;
  10. }
  11. public static class Info2 {
  12. public boolean isFull;
  13. public int height;
  14. public Info2(boolean f, int h) {
  15. isFull = f;
  16. height = h;
  17. }
  18. }
  19. public static Info2 process2(Node h) {
  20. if (h == null) {
  21. return new Info2(true, 0);
  22. }
  23. Info2 leftInfo = process2(h.left);
  24. Info2 rightInfo = process2(h.right);
  25. boolean isFull = leftInfo.isFull && rightInfo.isFull && leftInfo.height == rightInfo.height;
  26. int height = Math.max(leftInfo.height, rightInfo.height) + 1;
  27. return new Info2(isFull, height);
  28. }

给定一颗二叉树的头结点,返回这颗二叉树中最大的二叉搜索子树的头结点

  1. public static Node maxSubBSTHead2(Node head) {
  2. if (head == null) {
  3. return null;
  4. }
  5. return process(head).maxSubBSTHead;
  6. }
  7. // 每一棵子树
  8. public static class Info {
  9. //最大搜索子树的头结点
  10. public Node maxSubBSTHead;
  11. //最大搜索子树的节点数
  12. public int maxSubBSTSize;
  13. //右树的最小值
  14. public int min;
  15. //左树的最大值
  16. public int max;
  17. public Info(Node h, int size, int mi, int ma) {
  18. maxSubBSTHead = h;
  19. maxSubBSTSize = size;
  20. min = mi;
  21. max = ma;
  22. }
  23. }
  24. public static Info process(Node X) {
  25. if (X == null) {
  26. return null;
  27. }
  28. Info leftInfo = process(X.left);
  29. Info rightInfo = process(X.right);
  30. int min = X.value;
  31. int max = X.value;
  32. Node maxSubBSTHead = null;
  33. int maxSubBSTSize = 0;
  34. if (leftInfo != null) {
  35. min = Math.min(min, leftInfo.min);
  36. max = Math.max(max, leftInfo.max);
  37. maxSubBSTHead = leftInfo.maxSubBSTHead;
  38. maxSubBSTSize = leftInfo.maxSubBSTSize;
  39. }
  40. if (rightInfo != null) {
  41. min = Math.min(min, rightInfo.min);
  42. max = Math.max(max, rightInfo.max);
  43. if (rightInfo.maxSubBSTSize > maxSubBSTSize) {
  44. maxSubBSTHead = rightInfo.maxSubBSTHead;
  45. maxSubBSTSize = rightInfo.maxSubBSTSize;
  46. }
  47. }
  48. if ((leftInfo == null ? true : (leftInfo.maxSubBSTHead == X.left && leftInfo.max < X.value))
  49. && (rightInfo == null ? true : (rightInfo.maxSubBSTHead == X.right && rightInfo.min > X.value))) {
  50. maxSubBSTHead = X;
  51. maxSubBSTSize = (leftInfo == null ? 0 : leftInfo.maxSubBSTSize)
  52. + (rightInfo == null ? 0 : rightInfo.maxSubBSTSize) + 1;
  53. }
  54. return new Info(maxSubBSTHead, maxSubBSTSize, min, max);
  55. }