处理用时最长的那个任务的员工

106 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情

🎈算法并不一定都是很难的题目,也有很多只是一些代码技巧,多进行一些算法题目的练习,可以帮助我们开阔解题思路,提升我们的逻辑思维能力,也可以将一些算法思维结合到业务代码的编写思考中。简而言之,平时进行的算法习题练习带给我们的好处一定是不少的,所以让我们一起来养成算法练习的习惯。今天练习的题目是一道比较简单的题目 -> 处理用时最长的那个任务的员工

题目描述

共有 n 位员工,每位员工都有一个从 0 到 n - 1 的唯一 id 。

给你一个二维整数数组 logs ,其中 logs[i] = [idi, leaveTimei] :

idi 是处理第 i 个任务的员工的 id ,且 leaveTimei 是员工完成第 i 个任务的时刻。所有 leaveTimei 的值都是 唯一 的。 注意,第 i 个任务在第 (i - 1) 个任务结束后立即开始,且第 0 个任务从时刻 0 开始。

返回处理用时最长的那个任务的员工的 id 。如果存在两个或多个员工同时满足,则返回几人中 最小 的 id 。

示例 1:

输入:n = 10, logs = [[0,3],[2,5],[0,9],[1,15]]
输出:1
解释:
任务 0 于时刻 0 开始,且在时刻 3 结束,共计 3 个单位时间。
任务 1 于时刻 3 开始,且在时刻 5 结束,共计 2 个单位时间。
任务 2 于时刻 5 开始,且在时刻 9 结束,共计 4 个单位时间。
任务 3 于时刻 9 开始,且在时刻 15 结束,共计 6 个单位时间。
时间最长的任务是任务 3 ,而 id 为 1 的员工是处理此任务的员工,所以返回 1

示例 2:

输入:n = 26, logs = [[1,1],[3,7],[2,12],[7,17]]
输出:3
解释:
任务 0 于时刻 0 开始,且在时刻 1 结束,共计 1 个单位时间。
任务 1 于时刻 1 开始,且在时刻 7 结束,共计 6 个单位时间。
任务 2 于时刻 7 开始,且在时刻 12 结束,共计 5 个单位时间。
任务 3 于时刻 12 开始,且在时刻 17 结束,共计 5 个单位时间。
时间最长的任务是任务 1 ,而 id 为 3 的员工是处理此任务的员工,所以返回 3

示例 3:

输入:n = 2, logs = [[0,10],[1,20]]
输出:0
解释:
任务 0 于时刻 0 开始,且在时刻 10 结束,共计 10 个单位时间。
任务 1 于时刻 10 开始,且在时刻 20 结束,共计 10 个单位时间。
时间最长的任务是任务 01 ,处理这两个任务的员工的 id 分别是 01 ,所以返回最小的 0

提示:

  • 2 <= n <= 500
  • 1 <= logs.length <= 500
  • logs[i].length == 2
  • 0 <= idi <= n - 1
  • 1 <= leaveTimei <= 500
  • idi != idi + 1
  • leaveTimei 按严格递增顺序排列

思路分析

首先我们要先理解一下题目的意思,题目会给我们一个数字n和一个数组logs,数字n代表 n 位员工,每位员工都有一个从 0 到 n - 1 的唯一 id ,logs为二维整数数组,其中 logs[i] = [idi, leaveTimei],idi 是处理第 i 个任务的员工的 id ,且leaveTimei 是员工完成第 i 个任务的时刻。所有 leaveTimei 的值都是 唯一 的。

我们需要找到处理用时最长的那个任务的员工的 id 。如果存在两个或多个员工同时满足,则返回几人中 最小 的 id 。

了解了题目的要求之后,我们知道了我们只需要计算所有任务处理时长,找到处理时长最大的那个任务的员工即可。

我们可以根据任务处理时长进行分类统计,将任务处理时长一样的员工放到同一个数组,最后只需要找到任务处理时长中最长的那个数组中最小的id即可。

  • 1、计算任务处理时间 第 i 个任务在第 (i - 1) 个任务结束后立即开始,且第 0 个任务从时刻 0 开始。所以每一个任务的处理时间是当前任务结束时间 - 上一个任务结束时间
let map = {},max = 0;
for(let i = 0; i < logs.length; i++){
    const time = logs[i][1] - (i == 0 ? 0 : logs[i - 1][1]);
    ……
    ……
}
  • 2、根据处理时间分组
for(let i = 0; i < logs.length; i++){
    const time = logs[i][1] - (i == 0 ? 0 : logs[i - 1][1]);
    if(!map[time]) map[time] = [];
    map[time].push(logs[i][0]);
}
  • 3、记录最大的处理时间
for(let i = 0; i < logs.length; i++){
    const time = logs[i][1] - (i == 0 ? 0 : logs[i - 1][1]);
    if(!map[time]) map[time] = [];
    map[time].push(logs[i][0]);
    max = Math.max(max,time);
}
  • 4、返回最小的id
return Math.min(... map[max]);
  • 优化 在上面代码中我们需要将所有的员工id根据处理时间分组保存起来,但是最后需要的只是处理时长最长id最小的员工id,其他保存起来的数据并没有什么用,这样是耗费和很多不必要的空间,因此我们可以只保存我们需要的那个id。

完整AC代码如下:

AC代码

/**
 * @param {number} n
 * @param {number[][]} logs
 * @return {number}
 */
 var hardestWorker = function(n, logs) {
    let maxTime = 0,res = 0;
    for(let i = 0; i < logs.length; i++){
        const time = logs[i][1] - (i == 0 ? 0 : logs[i - 1][1]);
        if(maxTime < time){
            maxTime = time;
            res = logs[i][0];
        }else if(maxTime == time){
            res = Math.min(res,logs[i][0]);
        }
    }
    return res;
};

说在后面

🎉这里是JYeontu,喜欢算法,GDCPC打过卡;热爱羽毛球,大运会打过酱油。毕业一年,两年前端开发经验,目前担任H5前端开发,算法业余爱好者,有空会刷刷算法题,平时喜欢打打羽毛球🏸 ,也喜欢写些东西,既为自己记录📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解🙇,写错的地方望指出,定会认真改进😊,在此谢谢大家的支持,我们下文再见🙌。