题意:
有一颗节点为 n 的树,初始时每个节点的值都是0。
现有 m 次操作,每次操作为选定其中一个节点,使得该节点和与该节点直接相邻的节点的值都加 1 。
问最后每个节点的值为多少?
方法一
模拟
思路:用邻接表建树。
遍历每次操作,将选中的某节点和与某节点直接相邻的节点的值都加 1 。最后返回数组。
class Solution {
public:
vector<int> solve(int n, int m, vector<int>& u, vector<int>& v, vector<int>& q) {
vector<vector<int>> g(n+1);
vector<int> res(n);//记录每个节点的值
for(int i=0;i<n-1;i++){//建树
g[u[i]].push_back(v[i]);//无向
g[v[i]].push_back(u[i]);
}
for(int i=0;i<m;i++){//遍历每次操作
int x=q[i];
res[q[i]-1]++;//某节点值加一
int num=g[x].size();
for(int i=0;i<num;i++){
int y=g[x][i];
res[y-1]++;//与某节点直接相邻的节点值加一
}
}
return res;
}
};
时间复杂度:
空间复杂度:![]()
方法二:
思维
思路:每个节点的值=自己本身增加的数量+与其他节点直接相邻而增加的数量。
因此,我们可以先遍历一次修改数组,得到自己本身增加的数量;再遍历每条边,得到与其他节点直接相邻而增加的数量。最后,将两者相加,即可得到每个节点的值。
class Solution {
public:
vector<int> solve(int n, int m, vector<int>& u, vector<int>& v, vector<int>& q) {
vector<int> res(n);//记录每个节点的值
vector<int> x(n);//自己本身增加的数量
vector<int> y(n);//与其他节点直接相邻而增加的数量
for(int i=0;i<m;i++){
x[q[i]-1]++;//本身增加的值
}
for(int i=0;i<n-1;i++){//遍历每条边
y[u[i]-1]+=x[v[i]-1];
y[v[i]-1]+=x[u[i]-1];
}
for(int i=0;i<n;i++)
res[i]=x[i]+y[i];//相加
return res;
}
};
时间复杂度:
空间复杂度:![]()



京公网安备 11010502036488号