- 统计最高分的节点数目
给你一棵根节点为 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;
}
};