前端刷题路-Day43:员工的重要性(题号690)

169 阅读4分钟

这是我参与更文挑战的第7天,活动详情查看: 更文挑战

员工的重要性(题号690)

题目

给定一个保存员工信息的数据结构,它包含了员工 唯一的 id重要度直系下属的 id

比如,员工 1 是员工 2 的领导,员工 2 是员工 3 的领导。他们相应的重要度为 15 , 10 , 5 。那么员工 1 的数据结构是 [1, 15, [2]] ,员工 2的 数据结构是 [2, 10, [3]] ,员工 3 的数据结构是 [3, 5, []] 。注意虽然员工 3 也是员工 1 的一个下属,但是由于并不是直系 下属,因此没有体现在员工 1 的数据结构中。

现在输入一个公司的所有员工信息,以及单个员工 id ,返回这个员工和他所有下属的重要度之和。

示例:

输入:[[1, 5, [2, 3]], [2, 3, []], [3, 3, []]], 1
输出:11
解释:
员工 1 自身的重要度是 5 ,他有两个直系下属 2 和 3 ,而且 2 和 3 的重要度均为 3 。因此员工 1 的总重要度是 5 + 3 + 3 = 11

提示:

  • 一个员工最多有一个 直系 领导,但是可以有多个 直系 下属
  • 员工数量不超过 2000

链接

leetcode-cn.com/problems/em…

解释

这题其实比较简单了,属于那种一看就知道答案的问题,解决方案也有很多种。

核心就是对领导的多个下属进行多次查找,用递归和迭代都可以,借助Map可以更快的找到下属,但会占用额外的空间。

自己的答案(Map+迭代)

先看代码👇:

var GetImportance = function (employees, id) {
  var obj = new Map()
      res = 0
      root = [id]
  for (const item of employees) {
    obj.set(item.id, item)
  }
  while (root.length) {
    var item = obj.get(root.pop())
    res += item.importance
    root = root.concat(item.subordinates)
  }
  return res
};

首先搞一个for循环,然后以idkey,将所有的员工都转化成一个Map,之后从给定的id开始查找,将当前元素的下属继续聚合到root中去,以此不断找到下属。

这种解法的执行用时很快,但是内存消耗较大,但没办法,毕竟新建了一个Map来存储员工数据,属于典型的用空间换时间解法。

自己的答案(纯迭代)

代码相比上一种解决方案更简单👇:

var GetImportance = function (employees, id) {
  var res = 0
      root = [id]
  while (root.length) {
    var activeId = root.pop()
        item = employees.find(item => item.id === activeId)
    res += item.importance
    root = root.concat(item.subordinates)
  }
  return res
};

去掉了存储Map的过程,每次都使用数组的find方法来进行查找操作,如此依赖,执行时间直接倒数30%,但是内存占用直接90%以上,因为除了rootres,并没有新增任何变量,如果需要用时间换空间,这可以是一种做法,而且从代码量上来更少了。

自己的答案(Map+递归)

和迭代的核心逻辑差不多,不同处就是将迭代替换成了递归,也就是深度优先搜索👇:

var GetImportance = function (employees, id) {
  var obj = new Map()
      res = 0
  for (const item of employees) {
    obj.set(item.id, item)
  }
  function dfs(id) {
    const { importance,  subordinates} = obj.get(id)
    var total = importance
    for (const itemId of subordinates) {
      total += dfs(itemId)
    }
    return total
  }
  return dfs(id)
};

没啥可说的,效果和Map+迭代差不多,运行时间相差无几,都很快,但内存占用也都很多。

自己的答案(纯递归)

纯递归的逻辑和纯迭代差不多,用的都是数组的find方法👇:

var GetImportance = function (employees, id) {
  function dfs(id) {
    const { importance,  subordinates} = employees.find(item => item.id === id)
    var total = importance
    for (const itemId of subordinates) {
      total += dfs(itemId)
    }
    return total
  }
  return dfs(id)
};

让人惊喜的是这种方法竟然是最折中的方法,运行速度不是最快的,内存占用也不是最多的,而都是70%左右👇:

img

如果需要取折中效果的话可以使用这种方法。

更好的答案



PS:想查看往期文章和题目可以点击下面的链接:

这里是按照日期分类的👇

前端刷题路-目录(日期分类)

经过有些朋友的提醒,感觉也应该按照题型分类
这里是按照题型分类的👇

前端刷题路-目录(题型分类)

有兴趣的也可以看看我的个人主页👇

Here is RZ