LeetCode Problem Workspace
Alert Using Same Key-Card Three or More Times in a One Hour Period
Solve LeetCode 1604 by grouping swipe times per employee, sorting each list, and scanning for any three within 60 minutes.
4
Topics
5
Code langs
3
Related
Practice Focus
Medium · Array scanning plus hash lookup
Answer-first summary
Solve LeetCode 1604 by grouping swipe times per employee, sorting each list, and scanning for any three within 60 minutes.
Ace coding interviews with Interview AiBoxInterview AiBox guidance for Array scanning plus hash lookup
The clean solution for Alert Using Same Key-Card Three or More Times in a One Hour Period is to group times by employee name, convert each time to minutes, sort each employee's list, and check every length-three window. If the difference between the first and third time is at most 60 minutes, that employee must be included. This works because any valid alert can be detected by three consecutive sorted swipes.
Problem Statement
In LeetCode 1604, each key-card record gives a worker name and a same-day access time in "HH:MM" format. You need to find every worker whose card was used at least three times during any one-hour span, then return those names in lexicographical order.
The main challenge is not counting total swipes, but detecting a tight local cluster of times for the same person. A worker with many accesses spread across the day should not trigger an alert, while three nearby timestamps like 10:00, 10:40, and 11:00 should, because the first and third swipe still fall inside a 60-minute window.
Examples
Example 1
Input: keyName = ["daniel","daniel","daniel","luis","luis","luis","luis"], keyTime = ["10:00","10:40","11:00","09:00","11:00","13:00","15:00"]
Output: ["daniel"]
"daniel" used the keycard 3 times in a one-hour period ("10:00","10:40", "11:00").
Example 2
Input: keyName = ["alice","alice","alice","bob","bob","bob","bob"], keyTime = ["12:01","12:00","18:00","21:00","21:20","21:30","23:00"]
Output: ["bob"]
"bob" used the keycard 3 times in a one-hour period ("21:00","21:20", "21:30").
Constraints
- 1 <= keyName.length, keyTime.length <= 105
- keyName.length == keyTime.length
- keyTime[i] is in the format "HH:MM".
- [keyName[i], keyTime[i]] is unique.
- 1 <= keyName[i].length <= 10
- keyName[i] contains only lowercase English letters.
Solution Approach
Group swipes by employee name
Build a hash map from name to an array of access times. Convert each "HH:MM" string into total minutes so the later comparison is arithmetic instead of string-based. This matches the problem's real structure: alerts are decided per employee, never across different names.
Sort each employee's access times
For every name, sort the collected minute values in ascending order. Sorting turns the one-hour check into a local scan, because if three swipes fit inside 60 minutes, they will appear as a consecutive triple after sorting. This is the key trade-off: pay sorting cost once to avoid expensive pairwise comparisons.
Scan consecutive triples and collect alert names
Walk each sorted list from index 2 onward and compare the current time with the time two positions earlier. If time[i] - time[i-2] <= 60, add that name to the result and stop scanning that person. Breaking early matters because the output needs each name once, not every triggering window.
Complexity Analysis
| Metric | Value |
|---|---|
| Time | Depends on the final approach |
| Space | Depends on the final approach |
Let n be the number of key-card records. Building the hash map and converting times costs O(n). If a worker has k accesses, sorting that worker's list costs O(k log k), so across all workers the total is O(n log n) in the worst case when most records belong to one person. The scan over sorted lists is linear, so total extra space is O(n) for the grouped time arrays and result storage.
What Interviewers Usually Probe
- You notice quickly that the alert condition is per name, so the first move is grouping by employee before doing any time logic.
- You convert "HH:MM" into minutes early, which avoids brittle string comparisons and makes the 60-minute rule exact.
- You justify why checking only sorted consecutive triples is enough, instead of comparing every combination of three accesses.
Common Pitfalls or Variants
Common pitfalls
- Treating one hour as needing the same clock hour, which incorrectly rejects windows like 10:40, 10:59, and 11:00.
- Sorting all records globally by time and trying to track alerts across names, which mixes unrelated employees and complicates the logic.
- Checking adjacent pairs instead of triples, which misses the actual trigger condition of three or more uses within one hour.
Follow-up variants
- Return the actual triggering time window for each employee instead of only the employee names.
- Raise an alert after k accesses within t minutes, which generalizes the same grouped sorting pattern to a wider sliding window.
- Handle multi-day logs, where converting times requires attaching a date so midnight crossings do not break minute comparisons.
FAQ
What is the best approach for Alert Using Same Key-Card Three or More Times in a One Hour Period?
Group all access times by employee, convert each time to minutes, sort each employee's list, and check whether any consecutive triple fits inside 60 minutes. That directly matches the alert rule and avoids overcomplicated comparisons.
Why is checking consecutive triples after sorting enough?
If any three accesses for one employee are within 60 minutes, those three times will appear in sorted order, and the earliest and latest of that triple will define a consecutive length-three window somewhere in the list. So comparing time[i] with time[i-2] is sufficient.
Is this really an array scanning plus hash lookup problem?
Yes. The hash map is used to collect times by employee, and the core detection step is an array scan over each sorted list of minutes. The sorting step is what makes that scan reliable for this exact alert condition.
How do you handle the HH:MM strings correctly?
Parse the hour and minute, then compute total minutes as hour * 60 + minute. Once converted, the one-hour condition becomes a simple subtraction check, which is cleaner and less error-prone than working with raw strings.
Why does the result need lexicographical order?
The problem requires the final list of alerted employee names to be sorted alphabetically. You can either sort the result at the end or rely on iterating names in sorted order after building the grouped map.
Solution
Solution 1: Hash Table + Sorting
First, we use a hash table $d$ to record all the clock-in times of each employee.
class Solution:
def alertNames(self, keyName: List[str], keyTime: List[str]) -> List[str]:
d = defaultdict(list)
for name, t in zip(keyName, keyTime):
t = int(t[:2]) * 60 + int(t[3:])
d[name].append(t)
ans = []
for name, ts in d.items():
if (n := len(ts)) > 2:
ts.sort()
for i in range(n - 2):
if ts[i + 2] - ts[i] <= 60:
ans.append(name)
break
ans.sort()
return ansContinue Topic
array
Practice more edge cases under the same topic.
arrow_forwardauto_awesomeContinue Pattern
Array scanning plus hash lookup
Expand the same solving frame across more problems.
arrow_forwardsignal_cellular_altSame Difficulty Track
Medium
Stay on this level to stabilize interview delivery.
arrow_forward