leetcode
leetcode 2501 ~ 2550
高访问员工

高访问员工

难度:

标签:

题目描述

You are given a 2D 0-indexed array of strings, access_times, with size n. For each i where 0 <= i <= n - 1, access_times[i][0] represents the name of an employee, and access_times[i][1] represents the access time of that employee. All entries in access_times are within the same day.

The access time is represented as four digits using a 24-hour time format, for example, "0800" or "2250".

An employee is said to be high-access if he has accessed the system three or more times within a one-hour period.

Times with exactly one hour of difference are not considered part of the same one-hour period. For example, "0815" and "0915" are not part of the same one-hour period.

Access times at the start and end of the day are not counted within the same one-hour period. For example, "0005" and "2350" are not part of the same one-hour period.

Return a list that contains the names of high-access employees with any order you want.

 

Example 1:

Input: access_times = [["a","0549"],["b","0457"],["a","0532"],["a","0621"],["b","0540"]]
Output: ["a"]
Explanation: "a" has three access times in the one-hour period of [05:32, 06:31] which are 05:32, 05:49, and 06:21.
But "b" does not have more than two access times at all.
So the answer is ["a"].

Example 2:

Input: access_times = [["d","0002"],["c","0808"],["c","0829"],["e","0215"],["d","1508"],["d","1444"],["d","1410"],["c","0809"]]
Output: ["c","d"]
Explanation: "c" has three access times in the one-hour period of [08:08, 09:07] which are 08:08, 08:09, and 08:29.
"d" has also three access times in the one-hour period of [14:10, 15:09] which are 14:10, 14:44, and 15:08.
However, "e" has just one access time, so it can not be in the answer and the final answer is ["c","d"].

Example 3:

Input: access_times = [["cd","1025"],["ab","1025"],["cd","1046"],["cd","1055"],["ab","1124"],["ab","1120"]]
Output: ["ab","cd"]
Explanation: "ab" has three access times in the one-hour period of [10:25, 11:24] which are 10:25, 11:20, and 11:24.
"cd" has also three access times in the one-hour period of [10:25, 11:24] which are 10:25, 10:46, and 10:55.
So the answer is ["ab","cd"].

 

Constraints:

  • 1 <= access_times.length <= 100
  • access_times[i].length == 2
  • 1 <= access_times[i][0].length <= 10
  • access_times[i][0] consists only of English small letters.
  • access_times[i][1].length == 4
  • access_times[i][1] is in 24-hour time format.
  • access_times[i][1] consists only of '0' to '9'.

代码结果

运行时间: 42 ms, 内存: 16.0 MB


/*
 * 题目思路:
 * 1. 使用 Java Stream API 对数据进行处理。
 * 2. 将访问时间转换为分钟并分组到相应的员工。
 * 3. 对每个员工的时间列表进行排序并检查是否存在连续的三次访问是在同一小时内。
 * 4. 如果存在这样的情况,将员工加入到高访问员工列表中。
 */

import java.util.*;
import java.util.stream.*;

public class HighAccessEmployeesStream {
    public List<String> getHighAccessEmployees(String[][] access_times) {
        // 将访问时间转换为分钟并分组到相应的员工
        Map<String, List<Integer>> accessMap = Arrays.stream(access_times)
                .collect(Collectors.groupingBy(
                        access -> access[0],
                        Collectors.mapping(access -> Integer.parseInt(access[1].substring(0, 2)) * 60 + Integer.parseInt(access[1].substring(2)),
                                Collectors.toList())));

        // 检查每个员工是否为高访问员工
        return accessMap.entrySet().stream()
                .filter(entry -> {
                    List<Integer> times = entry.getValue();
                    Collections.sort(times);
                    for (int i = 0; i <= times.size() - 3; i++) {
                        if (times.get(i + 2) - times.get(i) < 60) {
                            return true;
                        }
                    }
                    return false;
                })
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }
}

解释

方法:

首先,将每个员工的访问时间转换为分钟数,并使用哈希表将相同员工的访问时间归类到一起。然后,对每个员工的访问时间进行排序,以便我们可以按顺序检查时间间隔。接下来,我们检查每个员工的访问时间列表,如果在列表中存在任意连续三个时间点,它们的时间差小于60分钟,则将该员工视为高访问员工,并将其姓名添加到结果列表中。最后,返回结果列表。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
在实现中,如何确保`any(t[i] - t[i - 2] < 60 for i in range(2, len(t)))`这个条件正确地识别了同一小时内的访问?
这个条件通过检查员工的任意连续三个访问时间点是否相差少于60分钟来实现。首先,所有访问时间都被转换成分钟,并按时间顺序排序。然后,使用`range(2, len(t))`遍历时间列表,确保我们始终查看三个连续的时间点(i, i-1, i-2)。如果这三个时间点中最早和最晚的时间差小于60分钟,即`t[i] - t[i - 2] < 60`,则意味着这三个时间点在同一小时内。这样可以确保只要有任意三个连续访问时间满足这个条件,就可以将该员工标记为高访问员工。
🦆
在此算法中,是否考虑了同一分钟内多次访问的情况?例如员工在同一分钟内访问了三次。
在当前的实现中,并没有特别处理同一分钟内多次访问的情况。算法将所有访问时间转换为分钟后,如果一个员工在同一分钟内多次访问,这些访问会记录为相同的时间点。由于算法检查的是任意连续三个时间点的时间差,因此即使是在同一分钟内的三次访问也会被识别,并将该员工视为高访问员工。这意味着即使多次访问发生在同一分钟,也满足`any(t[i] - t[i - 2] < 60 for i in range(2, len(t)))`的条件,因为差值会是0。

相关问题