|
| 1 | +package code; |
| 2 | + |
| 3 | +import java.util.HashMap; |
| 4 | +import java.util.HashSet; |
| 5 | +/* |
| 6 | + * 834. Sum of Distances in Tree |
| 7 | + * 题意:求树中每个节点的值,到其他节点的距离和 |
| 8 | + * 难度:Hard |
| 9 | + * 分类:Tree, Depth-first Search |
| 10 | + * 思路:真的难,我是做不出来 |
| 11 | + * 两次遍历,第一次后续遍历,计算出每个节点为根的树,有几个孩子节点,并计算出root的结果 |
| 12 | + * 根据前一步的计算结果,开始先序遍历,一步步计算出其他节点的结果 |
| 13 | + * res[node] = res[parent]-2*count[node]+count.length; |
| 14 | + * https://leetcode.com/problems/sum-of-distances-in-tree/discuss/130583/C%2B%2BJavaPython-Pre-order-and-Post-order-DFS-O(N) |
| 15 | + * https://leetcode.com/problems/sum-of-distances-in-tree/discuss/130567/Two-traversals-O(N)-python-solution-with-Explanation |
| 16 | + * Tips: |
| 17 | + */ |
| 18 | +public class lc834 { |
| 19 | + public static void main(String[] args) { |
| 20 | + int[][] arr = {{0,1},{0,2},{2,3},{2,4},{2,5}}; |
| 21 | + sumOfDistancesInTree(6, arr); |
| 22 | + } |
| 23 | + |
| 24 | + static int[] count; |
| 25 | + static int[] res; |
| 26 | + static HashMap<Integer, HashSet<Integer>> hm = new HashMap(); |
| 27 | + public static int[] sumOfDistancesInTree(int N, int[][] edges) { |
| 28 | + if(edges.length==0) return new int[]{0}; |
| 29 | + count = new int[N]; //记录n为跟的树,下边有多少个节点 |
| 30 | + res = new int[N]; |
| 31 | + for (int i = 0; i < edges.length ; i++) { //双向都添加,遍历的时候判断一下,因为并不一定0就是根 |
| 32 | + HashSet<Integer> hs = hm.getOrDefault(edges[i][0], new HashSet()); |
| 33 | + hs.add(edges[i][1]); |
| 34 | + hm.put(edges[i][0], hs); |
| 35 | + hs = hm.getOrDefault(edges[i][1], new HashSet()); |
| 36 | + hs.add(edges[i][0]); |
| 37 | + hm.put(edges[i][1], hs); |
| 38 | + } |
| 39 | + helper1(0, -1); |
| 40 | + helper2(0, -1); |
| 41 | + return res; |
| 42 | + } |
| 43 | + |
| 44 | + public static int helper1(int node, int parent){ //后序遍历,求root对应的结果,计算每个节点的count |
| 45 | + HashSet<Integer> hs = hm.getOrDefault(node, new HashSet()); |
| 46 | + for (Integer i:hs) { |
| 47 | + if(i==parent) continue; //是parent的话直接略过 |
| 48 | + count[node] += helper1(i, node); |
| 49 | + res[node] += res[i] + count[i]; |
| 50 | + } |
| 51 | + count[node]++; |
| 52 | + return count[node]; |
| 53 | + } |
| 54 | + |
| 55 | + public static void helper2(int node, int parent){ //先序遍历,求结果 |
| 56 | + HashSet<Integer> hs = hm.getOrDefault(node, new HashSet()); |
| 57 | + if(node!=0) |
| 58 | + res[node] = res[parent]-2*count[node]+count.length; //转移计算 |
| 59 | + for (Integer i:hs) { |
| 60 | + if(i==parent) continue; //是parent的话直接略过 |
| 61 | + helper2(i, node); |
| 62 | + } |
| 63 | + } |
| 64 | +} |
0 commit comments