题目描述:
给你一棵根节点为 0 的 二叉树 ,它总共有 n 个节点,节点编号为 0 到 n - 1 。同时给你一个下标从 0 开始的整数数组 parents 表示这棵树,其中 parents[i] 是节点 i 的父节点。由于节点 0 是根,所以 parents[0] == -1 。
一个子树的 大小 为这个子树内节点的数目。每个节点都有一个与之关联的 分数 。求出某个节点分数的方法是,将这个节点和与它相连的边全部 删除 ,剩余部分是若干个 非空 子树,这个节点的 分数 为所有这些子树 大小的乘积 。
请你返回有 最高得分 节点的 数目 。
方法一:
class node
{
public:
node* left;
node* right;
int leftcount; //左子树中所含的节点数
int rightcount; //右子树中所含的节点数
node()
{
left = nullptr;
right = nullptr;
leftcount = 0;
rightcount = 0;
}
};
class Solution {
public:
int count(node* cur) //计算各个节点的左右子树各自的节点个数
{
if (cur == nullptr) return 0;
cur->leftcount = count(cur->left);
cur->rightcount = count(cur->right);
return cur->leftcount + cur->rightcount + 1;
}
int countHighestScoreNodes(vector<int>& parents) {
int n = parents.size();
vector<node*> nodes(n);
//对各个节点初始化
for (int i = 0; i < n; i++)
{
nodes[i] = new node();
}
node* root = new node(); //根节点
for (int i = 0; i < n; i++)
{
//当前遍历到的节点是i,它的父节点是par
int par = parents[i];
if (par == -1)
{
root = nodes[i];
}
else
{
if (nodes[par]->left == nullptr)
{
nodes[par]->left = nodes[i];
}
else
{
nodes[par]->right = nodes[i];
}
}
}
count(root);
//开始寻找最高得分的节点的数目
int ans = 0; //最高得分的节点的数目
long long maxscore = LONG_MIN; //最高得分
for (int i = 0; i < n; i++)
{
long long curscore = 0;
//由于要进行乘法运算,所以如果a、b、c为0的话,就把他们设为1
long long a = nodes[i]->leftcount == 0 ? 1 : nodes[i]->leftcount; //左子树的节点个数
long long b = nodes[i]->rightcount == 0 ? 1 : nodes[i]->rightcount; //右子树的节点个数
long long c = n - nodes[i]->leftcount - nodes[i]->rightcount - 1; //nodes[i]去掉与其父节点连接的边后,其父节点一方的节点个数
c = c == 0 ? 1 : c; //如果nodes[i]是根节点的情况,那么就让c为1
curscore = a * b * c;
//cout << a << " " << b << " " << c << endl;;
if (curscore > maxscore)
{
maxscore = curscore;
ans = 1;
}
else if (curscore == maxscore)
{
ans++;
}
}
return ans;
}
};
昨天周赛的第三题。
我的想法是通过parents构造一棵完整的二叉树,然后再遍历一遍,计算各个节点的左子树的结点个数和右子树的节点个数。
最后计算分数时,分为三个部分:与左节点连接的边、与右右节点连接的边和与父节点连接的边。
例如上图中的节点2,他的左子树的结点个数为1;右子树的结点个数为1;去掉与父节点所连接的边后,就相当于将以节点2为根节点的子树从这整棵树中去掉,所以用整棵树的节点个数n减去这棵子树,为 n - 3 = 2。最后将三部分相乘即为答案。
注意由于分数的计算方式是乘法,所以若a、b、c中有一个的值为0,就将其设为1,防止导致乘法结果为0。