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

该博客介绍了一道LeetCode题目,涉及员工使用员工卡开门并触发警告的情况。当员工在一小时内使用卡超过或等于三次时,系统会发出警告。解决方案是通过哈希表存储员工名字和打卡时间,并利用滑动窗口检查是否存在一小时内打卡三次的员工。文章详细解释了如何将时间转换为数字,以及如何实施哈希表和滑动窗口算法来找出警告名单。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:https://leetcode-cn.com/problems/alert-using-same-key-card-three-or-more-times-in-a-one-hour-period/

leetcode题解: https://leetcode-cn.com/problems/alert-using-same-key-card-three-or-more-times-in-a-one-hour-period/solution/ha-xi-biao-hua-dong-chuang-kou-hao-shi-z-z6lj/

 题意:

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

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

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

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

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

 方法:利用哈希表的性质,将用户的姓名和打卡时间的关系映射成哈希表,再者把时间从字符串转化成数字,利用滑动窗口寻找每个用户是否存在一小时内打卡次数满3次的情况。

bool cmp(int s1,int s2)
{
    return s1<s2;
}
bool cmp1(string s1,string s2)
{
    return s1<s2;
}
class Solution {
public:
    vector<string> alertNames(vector<string>& keyName, vector<string>& keyTime) {
        unordered_map<string,vector<int>> mp;//哈希表<key,value>等价于<姓名,打卡时间>
        vector<string> name;
        for(int i=0;i<keyName.size();i++)
        {
            int hour=(keyTime[i][0]-'0')*10+(keyTime[i][1]-'0');
            int minute=(keyTime[i][3]-'0')*10+(keyTime[i][4]-'0');
            mp[keyName[i]].emplace_back(hour*60+minute);
        }
        for(auto iter=mp.begin();iter!=mp.end();iter++)
        {
            sort((iter->second).begin(),(iter->second).end(),cmp);//按时间先后排序
            if((iter->second).size()<3) continue;//打卡时刻小于3的话,就不需要看这个人的打卡时刻
            int left=0,right=1,len = (iter->second).size(),cnt=0;//滑动窗口左侧坐标,滑动窗口右侧坐标,vector总长度,记录一小时内的打卡次数
            int deadline = 60;//一小时=60分钟
            int initialTime = ((iter->second)[left]);
            while(right<len)//滑动窗口右侧坐标滑动到向量的最大长度结束
            {
                int thisTime = ((iter->second)[right]);
                cnt++;//计数次数自加
                if(thisTime-initialTime<=deadline)//计算时间差
                {
                    if(cnt==2)//如果满足条件就把员工姓名放入向量中,并且退出此次滑动窗口滑动的过程
                    {
                        name.emplace_back(iter->first);
                        break;
                    }
                }
                while(thisTime-initialTime>deadline)//如果和起始时间相差超过1小时,就说明离得过远,窗口左侧坐标右移
                {
                    left++;//滑动窗口左坐标右移
                    cnt--;//计数次数减一
                    initialTime = ((iter->second)[left]);//更新滑动窗口左侧对应的坐标
                    if(cnt==0) break;//cnt计数次数如果是0代表着滑动窗口左侧坐标等于右侧坐标,结束此层循环
                }
                right++;//滑动窗口右坐标右移
            }
        }
        sort(name.begin(),name.end(),cmp1);
        return name;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值