Leetcode 834. 树中距离之和 C++

Leetcode 834. 树中距离之和

题目

给定一个无向、连通的树。树中有 N 个标记为 0…N-1 的节点以及 N-1 条边 。

第 i 条边连接节点 edges[i][0] 和 edges[i][1] 。

返回一个表示节点 i 与其他所有节点距离之和的列表 ans。

示例:

输入: N = 6, edges = [[0,1],[0,2],[2,3],[2,4],[2,5]]
输出: [8,12,6,10,10,10]
解释: 
如下为给定的树的示意图:
  0
 / \
1   2
   /|\
  3 4 5

我们可以计算出 dist(0,1) + dist(0,2) + dist(0,3) + dist(0,4) + dist(0,5) 
也就是 1 + 1 + 2 + 2 + 2 = 8。 因此,answer[0] = 8,以此类推。

说明: 1 <= N <= 10000

题解

dfs
将一棵树拆成两个子树,子树的根节点分别为A、B,显然A、B节点是相邻的。我们可得所有节点到A的距离和ans[A] = A子树中所有节点到A节点的距离和sum[A]+B子树中所有节点到B节点的距离和sum[B]+Bz子树中节点个数cnt[B],我们简写为ans[A] = sum[A] + sum[B] + cnt[B];同理,我们可以得到ans[B] = sum[B] + sum[A] + cnt[A]。
两式作差可以得到ans[A] = cnt[B] - cnt[A] + ans[B],因为cnt[A]+cnt[B] = N的,因此ans[A] = cnt[B] - cnt[A] + ans[B] + cnt[A] - cnt[A] = ans[B] - cnt[A] + (N-cnt[A])。我们不妨把A看作子节点,B看作是父节点。
我们两次dfs,一次获取每个节点作为根节点的子树中节点的个数,即cnt;一次用来获取答案,也就是ans。
详细过程见代码

代码

	vector<int> visit;
    vector<int> cnt;
    int dfs(int now,int height,unordered_map<int,vector<int>>& tree){
        int ans = height;
        visit[now] = 1;
        for(int i=0; i<tree[now].size(); i++){
            if(visit[tree[now][i]] == 0){
                ans += dfs(tree[now][i],height+1,tree);
                cnt[now] += cnt[tree[now][i]]; 
            }
        }
        cnt[now]++;
        return ans;
    }
    //ans[x] = x@ + y@ + cnty
    //ans[y] = y@ + x@ + cntx
    //ans[x] = ans[y] + cnty -cntx
    void dfs2(int now,int parent,int N,vector<int>&ans,unordered_map<int,vector<int>>& tree){
        visit[now] = 1;
        if(parent!=-1){
            ans[now] = ans[parent] - cnt[now] + (N-cnt[now]);
        }
        for(int i=0; i<tree[now].size(); i++){
            if(visit[tree[now][i]] == 0){
                dfs2(tree[now][i],now,N,ans,tree);
            }
        }
    }
    vector<int> sumOfDistancesInTree(int N, vector<vector<int>>& edges) {
        unordered_map<int,vector<int>> tree;
        vector<int> ans(N,0);
        visit = vector<int>(N,0);
        cnt = vector<int>(N,0);
        for(int i=0; i<edges.size(); i++){
            tree[edges[i][0]].push_back(edges[i][1]);
            tree[edges[i][1]].push_back(edges[i][0]);
        }
        ans[0] = dfs(0,0,tree);		//统一将0作为树的根节点
        visit = vector<int>(N,0);
        dfs2(0,-1,N,ans,tree);
        return ans;
    }

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sum-of-distances-in-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值