2049. 统计最高分的节点数目(中等)

  1. 统计最高分的节点数目
    给你一棵根节点为 0 的 二叉树 ,它总共有 n 个节点,节点编号为 0 到 n - 1 。同时给你一个下标从 0 开始的整数数组 parents 表示这棵树,其中 parents[i] 是节点 i 的父节点。由于节点 0 是根,所以 parents[0] == -1 。
    一个子树的 大小 为这个子树内节点的数目。每个节点都有一个与之关联的 分数 。求出某个节点分数的方法是,将这个节点和与它相连的边全部 删除 ,剩余部分是若干个 非空 子树,这个节点的 分数 为所有这些子树 大小的乘积 。
    请你返回有 最高得分 节点的 数目 。

1.dfs

class Solution {
public:
    vector<vector<int>>children;
    long long maxscore=0;
    int res=0;
    int n;
    int dfs(int index){
        long long sum=1;
        int size=1;
        for(int &x:children[index]){
            int tmp=dfs(x);
            sum*=tmp;
            size+=tmp;
        }
        sum*=max(1,n-size);
        if(sum>maxscore){
            maxscore=sum;
            res=1;
        }else if(sum==maxscore){
            res++;
        }
        return size;
    }
    int countHighestScoreNodes(vector<int>& parents) {
        n=parents.size();
        children.resize(n,vector<int>());
        for(int i=0;i<n;i++){
            if(parents[i]!=-1){
                children[parents[i]].push_back(i);
            }
        }
        dfs(0);
        return res;
    }
};

2.提前计算好每个节点作为根节点的子树的大小

class Solution {
public:
    vector<vector<int>>children;
    //统计每个节点作为根节点时子树的大小
    int getchildren(int root,vector<int>& nums) { 
        if (children[root].size() == 0) {
            nums[root]=1;
            return 1;
        }
        int res=1;
        for (int i = 0; i < children[root].size(); i++) {
            int tmp=children[root][i];
            //如果该节点已经统计,则无需再递归,节省计算
            if(nums[tmp]==-1){
                nums[tmp]=getchildren(tmp,nums);
            }      
            res+=nums[tmp];
        }
        return res;

    }
    int countHighestScoreNodes(vector<int>& parents) {
        int n = parents.size();
        children.resize(n, vector<int>());
        //统计每个节点的直接孩子
        for (int i = 1; i < n; i++) {
            if (parents[i] != '-1') {
                children[parents[i]].push_back(i);
            }
        }
        vector<int>nums(n,-1);
        nums[0] = getchildren(0,nums);
        int res = 0;
        long long maxscore=0;
        for (int i = 0; i < n; i++) {
            long long sum = 1;
            //去除每个节点后剩余部分:孩子节点作为根节点的子树,整棵树去掉当前节点为根的子树
            for (int j = 0; j < children[i].size(); j++) {
                sum *= nums[children[i][j]];
            }
            int j = i;
            sum *=max(1,(n-nums[i]));
            if (maxscore < sum) {
                maxscore = sum;
                res=1;
            }else if (maxscore == sum) {
                res++;
            }
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值