题目
给定一系列的任务,这些任务可能有依赖关系,有依赖关系须相继执行,没有依赖关系则可以同时执行。写一个函数,计算完成给定所有任务需要的时间。
//例如下面这些任务执行总时间为 4
const tasks = [
{
"name": "task1",
"time": 1,
"dependency": "",
},
{
"name": "task2",
"time": 2,
"dependency": "",
},
{
"name": "task3",
"time": 3,
"dependency": "task1"
},
];
今天在看牛客网的时候,看面经看到了这一道算法题,不算太难,正好检测一下这段时间学习算法的成果,所有做了一下。
分析
首先,分析一下给的例子这个题目的意思,如果两个任务之间没有依赖关系,那么就不需要等待,直接同步执行即可,如果一个任务依赖了其他的任务,那么就要等待其他任务完成之后才能执行,然后得出最后所有任务都执行完所花费的时间,如果这些任务没有多依赖,或者一个任务会被多个任务以来,就只需要一个双重for循环就可以做出来。
这个题目的核心其实只需要得到依赖时间最长的那一组的时间总和即可,这个时间就是所有任务都执行完的时间。因为这组所花费的任务时间是最长的,所有,其他任务都执行完了,这一组还没执行完,这组时间就是所有任务都执行完的时间。
因为任务有可能存在多个依赖或者深层次的依赖
const tasks = [
{
"name": "task1",
"time": 1,
"dependency": "",
},
{
"name": "task2",
"time": 2,
"dependency": "",
},
{
"name": "task3",
"time": 3,
"dependency": "task1"
},
{
"name": "task4",
"time": 3,
"dependency": "task1"
},
{
"name": "task5",
"time": 3,
"dependency": "task3"
},
{
"name": "task6",
"time": 3,
"dependency": "task3"
},
];
所以,我们不能只是单纯的判断一次依赖,需要深度的进行判断,所有这就需要用到递归了。使用递归的方式找到某个任务的所有依赖任务,以及依赖任务的依赖任务,把这些时间全部存储到一个数组中,最后计算出来数组的时间最长时间返回即可,代码如下:
const tasks = [
{
"name": "task1",
"time": 1,
"dependency": "",
},
{
"name": "task2",
"time": 2,
"dependency": "",
},
{
"name": "task3",
"time": 3,
"dependency": "task1"
}
];
// 找到所有依赖的最长时间一个数组即可
function getTime(tasks) {
// 执行完所有时间总和
let sum = 0
// 存储所有任务的对象
const nameArr = {}
// 依赖关系任务
const depen = []
for(let i = 0; i < tasks.length; i++){
if(depen.indexOf(tasks[i].name) === -1){
// 无依赖则赋值为空数组
nameArr[tasks[i].name] = [tasks[i].time]
dfs(tasks[i].name, nameArr[tasks[i].name], tasks, depen)
}
}
for (const prop in nameArr) {
let count = 0
nameArr[prop].forEach(item => {
count += item
});
count > sum ? sum = count : sum
}
return sum
}
// 递归实现
function dfs(depenName, arr, tasks, depen){
for(let i = 0; i < tasks.length; i++){
if(tasks[i].dependency && tasks[i].dependency === depenName){
// 如果依赖是这个任务,则存进数组中
arr.push(tasks[i].time)
depen.push(tasks[i].name)
// 继续递归
dfs(tasks[i].name, arr, tasks, depen)
}
}
}
getTime(tasks)