题意:
有一颗节点为 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; } };
时间复杂度:空间复杂度: