Sum of Distances in Tree


An undirected, connected tree with N nodes labelled 0...N-1 and N-1 edges are given.

The ith edge connects nodes edges[i][0] and edges[i][1] together.

Return a list ans, where ans[i] is the sum of the distances between node i and all other nodes.

Example 1:

Input: N = 6, edges = [[0,1],[0,2],[2,3],[2,4],[2,5]]
Output: [8,12,6,10,10,10]
Explanation: 
Here is a diagram of the given tree:
  0
 / \
1   2
   /|\
  3 4 5
We can see that dist(0,1) + dist(0,2) + dist(0,3) + dist(0,4) + dist(0,5)
equals 1 + 1 + 2 + 2 + 2 = 8.  Hence, answer[0] = 8, and so on.

Note: 1 <= N <= 10000


题目理解:用给定一个无向图,保证这个无向图可以构成树,这棵树有N个节点,问每一个节点到其他所有节点的距离之和

解题思路:可以很明显的看出来,如果用f(cur)表示cur节点到其他所有节点的距离之和,那么f(cur)与f(cur的父节点)之间是有关系的,仔细分析一下我们可以了解到:

f(cur)= f(cur的父节点)- cur的所有子节点个数 + (N - 2)

因为要知道每一个节点的子节点个数,因此首先要遍历一次整棵树,记录这一信息。每次只需要知道父节点的信息,因此我们考虑使用层次遍历。而且我们还需要计算出循环的第一个信息,即f(根节点),这样,就可以得到答案了。

class Solution {
	boolean[] visited;
	int[] numOfChild;
	Map<Integer, List<Integer>> connected;
	int sum;
	int[] res;
    public int[] sumOfDistancesInTree(int N, int[][] edges) {
        if(N < 2)
    		return new int[N];
        visited = new boolean[N];
        numOfChild = new int[N];
        Arrays.fill(numOfChild, -1);
        connected = new HashMap<Integer, List<Integer>>();
        for(int[] it : edges){
        	if(!connected.containsKey(it[0]))
        		connected.put(it[0], new ArrayList<Integer>());
        	connected.get(it[0]).add(it[1]);
        	if(!connected.containsKey(it[1]))
        		connected.put(it[1], new ArrayList<Integer>());
        	connected.get(it[1]).add(it[0]);
        }
        sum = 0;
        BFS(0, 0);
        //剩下的只需要遍历整棵树就可以
        Arrays.fill(visited, false);
        res = new int[N];
        res[0] = sum;
        helper(0, N);
        return res;
    }
    
    public int BFS(int root, int layer){
    	sum += layer;
    	if(numOfChild[root] != -1)
    		return numOfChild[root];
    	visited[root] = true;
    	int num = 0;
    	for(int child : connected.get(root)){
    		if(visited[child])//如果是上层节点,就不访问
    			continue;
    		num += BFS(child, layer + 1) + 1;
    	}
    	numOfChild[root] = num;
    	return num;
    }
    
    public void helper(int root, int N){
    	visited[root] = true;
    	for(int child : connected.get(root)){
    		if(visited[child])//如果是上层节点,就不访问
    			continue;
    		int temp = res[root] - 2 * numOfChild[child] + N - 2;
    		//System.out.println(root + " " + child + " " + res[root] + " " + numOfChild[child]);
    		res[child] = temp;
    		helper(child, N);
    	}
    }
}

猜你喜欢

转载自blog.csdn.net/m0_37889928/article/details/80389961