题意:

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