import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;/** * 给定一颗二叉树的头节点head,任何两个节点之间都存在距离,返回整棵二叉树的最大距离 * 距离定义,从a节点走到b节点,经过的路线上所有节点的数量 */public class Code06_MaxDistance { public static class Node { public int value; public Node left; public Node right; public Node(int data) { this.value = data; } } public static int maxDistance1(Node head) { if (head == null) { return 0; } ArrayList<Node> arr = getPrelist(head); HashMap<Node, Node> parentMap = getParentMap(head); int max = 0; for (int i = 0; i < arr.size(); i++) { for (int j = i; j < arr.size(); j++) { max = Math.max(max, distance(parentMap, arr.get(i), arr.get(j))); } } return max; } public static ArrayList<Node> getPrelist(Node head) { ArrayList<Node> arr = new ArrayList<>(); fillPrelist(head, arr); return arr; } public static void fillPrelist(Node head, ArrayList<Node> arr) { if (head == null) { return; } arr.add(head); fillPrelist(head.left, arr); fillPrelist(head.right, arr); } public static HashMap<Node, Node> getParentMap(Node head) { HashMap<Node, Node> map = new HashMap<>(); map.put(head, null); fillParentMap(head, map); return map; } public static void fillParentMap(Node head, HashMap<Node, Node> parentMap) { if (head.left != null) { parentMap.put(head.left, head); fillParentMap(head.left, parentMap); } if (head.right != null) { parentMap.put(head.right, head); fillParentMap(head.right, parentMap); } } public static int distance(HashMap<Node, Node> parentMap, Node o1, Node o2) { HashSet<Node> o1Set = new HashSet<>(); Node cur = o1; o1Set.add(cur); while (parentMap.get(cur) != null) { cur = parentMap.get(cur); o1Set.add(cur); } cur = o2; while (!o1Set.contains(cur)) { cur = parentMap.get(cur); } Node lowestAncestor = cur; cur = o1; int distance1 = 1; while (cur != lowestAncestor) { cur = parentMap.get(cur); distance1++; } cur = o2; int distance2 = 1; while (cur != lowestAncestor) { cur = parentMap.get(cur); distance2++; } return distance1 + distance2 - 1; }// public static int maxDistance2(Node head) {// return process(head).maxDistance;// }//// public static class Info {// public int maxDistance;// public int height;//// public Info(int dis, int h) {// maxDistance = dis;// 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 maxDistance = Math.max(// Math.max(leftInfo.maxDistance, rightInfo.maxDistance),// leftInfo.height + rightInfo.height + 1);// return new Info(maxDistance, height);// } /** * 第三步:主函数直接调用 * @param head * @return */ 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; } } /** * 第二步, 递归过程 * @param x * @return */ public static Info process(Node x) { // base case 判断 if (x == null) { return new Info(0, 0); } // 向左右子树要信息体 Info leftInfo = process(x.left); Info rightInfo = process(x.right); // 加工生成自己的信息体Info 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); } // for test public static Node generateRandomBST(int maxLevel, int maxValue) { return generate(1, maxLevel, maxValue); } // for test public static Node generate(int level, int maxLevel, int maxValue) { if (level > maxLevel || Math.random() < 0.5) { return null; } Node head = new Node((int) (Math.random() * maxValue)); head.left = generate(level + 1, maxLevel, maxValue); head.right = generate(level + 1, maxLevel, maxValue); return head; } public static void main(String[] args) { int maxLevel = 4; int maxValue = 100; int testTimes = 1000000; for (int i = 0; i < testTimes; i++) { Node head = generateRandomBST(maxLevel, maxValue); if (maxDistance1(head) != maxDistance2(head)) { System.out.println("Oops!"); } } System.out.println("finish!"); }}