zl程序教程

您现在的位置是:首页 >  其他

当前栏目

leetcode 690. 员工的重要性

2023-03-14 22:51:21 时间

1.深度优先搜索

  • 我们可以把员工与领导之间的对应关系变换成如下的树形图,当然不一定是二叉树结构,也可能是多叉树,即一个领导对应多个下属
  • 既然可以化成树形图,那么也就可以用递归(深度优先遍历)来进行求解,下面搬上我们的递归解题三部曲:
  • 结束条件:当前遍历到的这个人没有人从属于他,即没有人是他的下属
  • 返回值:返回当前这个人所有直接或者间接从属员工的重要性之和,包括自身
  • 本级递归做什么:遍历当前这个人的所有直接从属员工,计算直接或者间接从属员工的重要性之和,包括自身
class Solution {
public:
    int getImportance(vector<Employee*> employees, int id) 
    {
        //注意employees容器里面存放的员工信息不是按照id大小顺序排列,即下标为0的地方对应的id不一定为1
        for (Employee* e : employees)
        {
            if (e->id == id)
            {
                if (e->subordinates.empty())//如果当前员工没有下属,说明到达累加重要性的结束条件,那么返回当前员工自身的重要性即可
                    return e->importance;
                //遍历当前员工所有附属的员工,计算他们及他们附属员工的重要性,然后累加到total计数器上
                for (int subId : e->subordinates)
                    e->importance += getImportance(employees, subId);//累加起点值是算上当前员工自身的重要性
                return e->importance;
            }
        }
        return 0;
    }
};
  • 上面的递归解法有一个明显的硬伤计算每一次都需要循环取查找某个对应于当前传入id的员工,查找的过程很费时间,那么有没有什么办法,可以快速查找对应id的员工呢?
  • map映射
class Solution {
public:
    unordered_map<int, Employee*> mp;
    int getImportance(vector<Employee*> employees, int id) 
    {
        //先把每个员工对应id,映射到map容器中,方便通过id快速查找到某个员工
        for (auto& employer : employees)
        {
            mp[employer->id] = employer;
        }
        return dfs(id);
    }
    int dfs(int id)
    {
        Employee* em = mp[id];//获取当前id对应的员工
        if (em->subordinates.size() == 0)
            return em->importance;
        for (auto& subId : em->subordinates)
            em->importance += dfs(subId);
        return em->importance;
    }
};

2.广度优先搜索

class Solution {
public:
    //unordered_map<int, Employee*> mp;
    int getImportance(vector<Employee*> employees, int id) 
    {
        queue<Employee*> q;
        //可以看出,通过循环查找,很耗费时间
        for (auto& em : employees)
        {
            if (em->id == id)
            {
                q.push(em);//先把对应员工id为传入id的放入队列中
                break;
            }
        }
        int total = 0;//累加器
        while (!q.empty())
        {
            Employee* employer = q.front();
            q.pop();
            total += employer->importance;
            //把当前员工直属的附属员工放入队列中
            for (auto& subId : employer->subordinates)
            {
                for (auto& em : employees)
                {
                    if (em->id == subId)
                    {
                        q.push(em);
                        break;
                    }
                }
            }
        }
        return total;
    }
};
  • 与上面递归同样,每一次循环查找都很费时间和内存,因此需要用map映射
class Solution {
public:
    int getImportance(vector<Employee *> employees, int id) {
        unordered_map<int, Employee *> mp;
        for (auto &employee : employees) {
            mp[employee->id] = employee;
        }

        int total = 0;
        queue<int> que;
        que.push(id);
        while (!que.empty()) {
            int curId = que.front();
            que.pop();
            Employee *employee = mp[curId];
            total += employee->importance;
            for (int subId : employee->subordinates) {
                que.push(subId);
            }
        }
        return total;
    }
};