1. import java.util.ArrayList;
    2. import java.util.HashMap;
    3. import java.util.HashSet;
    4. /**
    5. * 给定一颗二叉树的头节点head,任何两个节点之间都存在距离,返回整棵二叉树的最大距离
    6. * 距离定义,从a节点走到b节点,经过的路线上所有节点的数量
    7. */
    8. public class Code06_MaxDistance {
    9. public static class Node {
    10. public int value;
    11. public Node left;
    12. public Node right;
    13. public Node(int data) {
    14. this.value = data;
    15. }
    16. }
    17. public static int maxDistance1(Node head) {
    18. if (head == null) {
    19. return 0;
    20. }
    21. ArrayList<Node> arr = getPrelist(head);
    22. HashMap<Node, Node> parentMap = getParentMap(head);
    23. int max = 0;
    24. for (int i = 0; i < arr.size(); i++) {
    25. for (int j = i; j < arr.size(); j++) {
    26. max = Math.max(max, distance(parentMap, arr.get(i), arr.get(j)));
    27. }
    28. }
    29. return max;
    30. }
    31. public static ArrayList<Node> getPrelist(Node head) {
    32. ArrayList<Node> arr = new ArrayList<>();
    33. fillPrelist(head, arr);
    34. return arr;
    35. }
    36. public static void fillPrelist(Node head, ArrayList<Node> arr) {
    37. if (head == null) {
    38. return;
    39. }
    40. arr.add(head);
    41. fillPrelist(head.left, arr);
    42. fillPrelist(head.right, arr);
    43. }
    44. public static HashMap<Node, Node> getParentMap(Node head) {
    45. HashMap<Node, Node> map = new HashMap<>();
    46. map.put(head, null);
    47. fillParentMap(head, map);
    48. return map;
    49. }
    50. public static void fillParentMap(Node head, HashMap<Node, Node> parentMap) {
    51. if (head.left != null) {
    52. parentMap.put(head.left, head);
    53. fillParentMap(head.left, parentMap);
    54. }
    55. if (head.right != null) {
    56. parentMap.put(head.right, head);
    57. fillParentMap(head.right, parentMap);
    58. }
    59. }
    60. public static int distance(HashMap<Node, Node> parentMap, Node o1, Node o2) {
    61. HashSet<Node> o1Set = new HashSet<>();
    62. Node cur = o1;
    63. o1Set.add(cur);
    64. while (parentMap.get(cur) != null) {
    65. cur = parentMap.get(cur);
    66. o1Set.add(cur);
    67. }
    68. cur = o2;
    69. while (!o1Set.contains(cur)) {
    70. cur = parentMap.get(cur);
    71. }
    72. Node lowestAncestor = cur;
    73. cur = o1;
    74. int distance1 = 1;
    75. while (cur != lowestAncestor) {
    76. cur = parentMap.get(cur);
    77. distance1++;
    78. }
    79. cur = o2;
    80. int distance2 = 1;
    81. while (cur != lowestAncestor) {
    82. cur = parentMap.get(cur);
    83. distance2++;
    84. }
    85. return distance1 + distance2 - 1;
    86. }
    87. // public static int maxDistance2(Node head) {
    88. // return process(head).maxDistance;
    89. // }
    90. //
    91. // public static class Info {
    92. // public int maxDistance;
    93. // public int height;
    94. //
    95. // public Info(int dis, int h) {
    96. // maxDistance = dis;
    97. // height = h;
    98. // }
    99. // }
    100. //
    101. // public static Info process(Node X) {
    102. // if (X == null) {
    103. // return new Info(0, 0);
    104. // }
    105. // Info leftInfo = process(X.left);
    106. // Info rightInfo = process(X.right);
    107. // int height = Math.max(leftInfo.height, rightInfo.height) + 1;
    108. // int maxDistance = Math.max(
    109. // Math.max(leftInfo.maxDistance, rightInfo.maxDistance),
    110. // leftInfo.height + rightInfo.height + 1);
    111. // return new Info(maxDistance, height);
    112. // }
    113. /**
    114. * 第三步:主函数直接调用
    115. * @param head
    116. * @return
    117. */
    118. public static int maxDistance2(Node head) {
    119. return process(head).maxDistance;
    120. }
    121. /**
    122. * 第一步,构建信息体
    123. */
    124. public static class Info {
    125. public int maxDistance; //树的最大距离
    126. public int height; //树的高度
    127. public Info(int m, int h) {
    128. maxDistance = m;
    129. height = h;
    130. }
    131. }
    132. /**
    133. * 第二步, 递归过程
    134. * @param x
    135. * @return
    136. */
    137. public static Info process(Node x) {
    138. // base case 判断
    139. if (x == null) {
    140. return new Info(0, 0);
    141. }
    142. // 向左右子树要信息体
    143. Info leftInfo = process(x.left);
    144. Info rightInfo = process(x.right);
    145. // 加工生成自己的信息体Info
    146. int height = Math.max(leftInfo.height, rightInfo.height) + 1;
    147. int p1 = leftInfo.maxDistance;
    148. int p2 = rightInfo.maxDistance;
    149. int p3 = leftInfo.height + rightInfo.height + 1;
    150. int maxDistance = Math.max(Math.max(p1, p2), p3);
    151. return new Info(maxDistance, height);
    152. }
    153. // for test
    154. public static Node generateRandomBST(int maxLevel, int maxValue) {
    155. return generate(1, maxLevel, maxValue);
    156. }
    157. // for test
    158. public static Node generate(int level, int maxLevel, int maxValue) {
    159. if (level > maxLevel || Math.random() < 0.5) {
    160. return null;
    161. }
    162. Node head = new Node((int) (Math.random() * maxValue));
    163. head.left = generate(level + 1, maxLevel, maxValue);
    164. head.right = generate(level + 1, maxLevel, maxValue);
    165. return head;
    166. }
    167. public static void main(String[] args) {
    168. int maxLevel = 4;
    169. int maxValue = 100;
    170. int testTimes = 1000000;
    171. for (int i = 0; i < testTimes; i++) {
    172. Node head = generateRandomBST(maxLevel, maxValue);
    173. if (maxDistance1(head) != maxDistance2(head)) {
    174. System.out.println("Oops!");
    175. }
    176. }
    177. System.out.println("finish!");
    178. }
    179. }