直径问题 Diameter Problems
2019-11-03 21:37:59
一、Diameter of Binary Tree
问题描述:
问题求解:
解法一、第一反应是树上动归,每个节点保存一下左右的最大深度,最后以每个节点作为中枢计算最大的长度即可。
public int diameterOfBinaryTree(TreeNode root) { Map<TreeNode, int[]> map = new HashMap<>(); dfs(root, map); int res = 0; for (TreeNode key : map.keySet()) { res = Math.max(res, map.get(key)[0] + map.get(key)[1]); } return res; } private int[] dfs(TreeNode root, Map<TreeNode, int[]> map) { if (root == null) return new int[]{-1, -1}; int[] l = dfs(root.left, map); int[] r = dfs(root.right, map); map.put(root, new int[]{Math.max(l[0], l[1]) + 1, Math.max(r[0], r[1]) + 1}); return map.get(root); }
解法二、不求直径,而是转求每个节点的最大深度,遍历的时候可以顺便得到直径。
public int diameterOfBinaryTree(TreeNode root) { int[] res = new int[1]; helper(root, res); return res[0]; } private int helper(TreeNode root, int[] res) { if (root == null) return 0; int l = helper(root.left, res); int r = helper(root.right, res); res[0] = Math.max(res[0], l + r); return Math.max(l, r) + 1; }
二、Tree Diameter
问题描述:
问题求解:
int res = 0; public int treeDiameter(int[][] edges) { Map<Integer, Set<Integer>> graph = new HashMap<>(); for (int[] edge : edges) { int u = edge[0]; int v = edge[1]; if (!graph.containsKey(u)) graph.put(u, new HashSet<>()); if (!graph.containsKey(v)) graph.put(v, new HashSet<>()); graph.get(u).add(v); graph.get(v).add(u); } helper(graph, 0, new HashSet<Integer>()); return res; } private int helper(Map<Integer, Set<Integer>> graph, int node, Set<Integer> used) { Integer first = null; Integer second = null; used.add(node); for (int next : graph.get(node)) { if (used.contains(next)) continue; int tmp = helper(graph, next, used); if (first == null || first < tmp) { second = first; first = tmp; } else if (second == null || second < tmp) second = tmp; } int l1 = first == null ? 0 : first + 1; int l2 = second == null ? 0 : second + 1; res = Math.max(res, l1 + l2); return l1; }