每日一题——警告一小时内使用相同员工卡大于等于三次的人

83 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情


1604. 警告一小时内使用相同员工卡大于等于三次的人

力扣公司的员工都使用员工卡来开办公室的门。每当一个员工使用一次他的员工卡,安保系统会记录下员工的名字和使用时间。如果一个员工在一小时时间内使用员工卡的次数大于等于三次,这个系统会自动发布一个 警告 。

给你字符串数组 keyName 和 keyTime ,其中 [keyName[i], keyTime[i]] 对应一个人的名字和他在 某一天 内使用员工卡的时间。

使用时间的格式是 24小时制 ,形如 "HH:MM" ,比方说 "23:51" 和 "09:49" 。

请你返回去重后的收到系统警告的员工名字,将它们按 字典序 升序 排序后返回。

请注意 "10:00" - "11:00" 视为一个小时时间范围内,而 "23:51" - "00:10" 不被视为一小时内,因为系统记录的是某一天内的使用情况。

示例 1:

输入: keyName = ["leslie","leslie","leslie","clare","clare","clare","clare"], keyTime = ["13:00","13:20","14:00","18:00","18:51","19:30","19:49"]
输出: ["clare","leslie"]

 

提示:

  • 1 <= keyName.length, keyTime.length <= 105
  • keyName.length == keyTime.length
  • keyTime 格式为 "HH:MM"
  • 保证 [keyName[i], keyTime[i]] 形成的二元对 互不相同
  • 1 <= keyName[i].length <= 10
  • keyName[i] 只包含小写英文字母。

思路

要想思路清晰,我们首先要将每个人的时间归类以分别判断,故需要一个哈希表存放员工姓名和时间列表的映射关系,然后对用户一一判断。

对于每一个用户来说,我们要将其时间进行排序,对于每个时间,判断其后的两个时间是否都在一小时内(只判断第二个时间即可,因为时间已经有序,若第二个时间在同一小时内,第一个时间也必定在同一小时内)。如果成立,则将其加入答案,停止遍历。

在判断时间时,可以将两个字符串同时转换成分钟数以供判断,题目要求判断同一天的时间差,故这样也避免了跨天时间判断问题。

题解

class Solution {
    public List<String> alertNames(String[] keyName, String[] keyTime) {
        Map<String, List<String>> map = new HashMap<>();
        int n = keyName.length;
        for(int i = 0; i < n; i++) {
            if(!map.containsKey(keyName[i])) {
                map.put(keyName[i], new ArrayList<>());
            }
            map.get(keyName[i]).add(keyTime[i]);
        }
        Map<String, Integer> cnt = new HashMap<>();
        List<String> ans = new ArrayList<>();
        for(Map.Entry<String, List<String>> entry: map.entrySet()) {
            String name = entry.getKey();
            List<String> list = entry.getValue();
            if(list.size() < 3) {
                continue;
            }
            Collections.sort(list);
            for(int i = 0; i < list.size() - 2; i++) {
                if(checkTime(list.get(i), list.get(i + 1)) && checkTime(list.get(i), list.get(i + 2))) {
                    ans.add(name);
                    break;
                }
            }
        }
        Collections.sort(ans);
        return ans;
    }

    private boolean checkTime(String t1, String t2) {
        int hour = Integer.parseInt(t2.substring(0, 2)) - Integer.parseInt(t1.substring(0, 2));
        int min = Integer.parseInt(t2.substring(3, 5)) - Integer.parseInt(t1.substring(3, 5));
        return hour * 60 + min <= 60;
    }
}