Talentd
FleetCode
Make and follow sheets.Sign in

Alert Using Same Key-Card Three or More Times in a One Hour Period solution and explanation

MediumArrayHash TableSortingString6 min read46.0% acceptanceUpdated 9 Apr 2026
LeetCode 1604. Alert Using Same Key-Card Three or More Times in a One Hour PeriodHappy Coding · 10:56 · 1K viewsWatch on YouTube
8 more videos on this problem
  1. LeetCode 1604. Alert Using Same Key-Card Three or More Times in a One Hour PeriodHappy Coding · 10:56 · 1K views
  2. Alert Using Same Key-Card Three or More Times in a One Hour Period | LeetCode 1604 | With Java CodeNate Santti · 16:30 · 1K views
  3. 1604. Alert Using Same Key-Card Three or More Times in a One Hour Period (Leetcode Medium)Programming Live with Larry · 10:06 · 391 views
  4. Alert Using Same Key Card Three or More Times in a One Hour PeriodLetsWalkTogether · 9:47 · 220 views
  5. Leetcode 1604 Alert Using Same Key Card Three or More Times in a One Hour - Medium ComplexityAlgorithmicIQ · 26:05 · 178 views
  6. LeetCode Solutions 1604. Alert Using Same Key-Card Three or More Times in a One Hour PeriodAbrar & Software Engineering · 17:26 · 168 views
  7. LeetCode 1604. [Medium] Alert Using Same Key-Card Three or More Times in a One Hour PeriodFrancesco Manicardi · 5:27 · 149 views
  8. 1604. Alert Using Same Key Card Three or More Times in a One Hour Period | Biweekly Contest 36Coding Gist · 10:02 · 74 views
  9. LeetCode 1604: Alert Using Same Key-Card Three or More Times in a One Hour PeriodAlitaCode · 29:42 · 4 views

The problem

LeetCode company workers use key-cards to unlock office doors. Each time a worker uses their key-card, the security system saves the worker's name and the time when it was used. The system emits an alert if any worker uses the key-card three or more times in a one-hour period.

You are given a list of strings keyName and keyTime where [keyName[i], keyTime[i]] corresponds to a person's name and the time when their key-card was used in a single day.

Access times are given in the 24-hour time format "HH:MM", such as "23:51" and "09:49".

Return a list of unique worker names who received an alert for frequent keycard use. Sort the names in ascending order alphabetically.

Notice that "10:00" - "11:00" is considered to be within a one-hour period, while "22:51" - "23:52" is not considered to be within a one-hour period.

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"]
Explanation: "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"]
Explanation: "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.

Approach overview

Problem Overview: Given employee names and key-card usage times, detect employees who used their card three or more times within any one-hour window. Return the employee names that trigger the alert, sorted lexicographically.

Approach 1: Sliding Window with Minute Conversion (O(n log n) time, O(n) space)

Group all access times by employee using a hash table. Convert each HH:MM timestamp into total minutes (hour * 60 + minute) so time comparisons become simple integer differences. For every employee, sort their access times using sorting. Then scan the sorted list with a small sliding window: if times[i] - times[i-2] <= 60, three accesses occurred within one hour and the employee triggers an alert. This works because the sorted order ensures the smallest possible window for any three consecutive entries. The approach is efficient and easy to reason about during interviews.

Approach 2: Heap-Based Tracking (O(n log n) time, O(n) space)

Maintain a min-heap of timestamps per employee. As each access event is processed, convert the time to minutes and push it into that employee's heap. Continuously remove entries older than 60 minutes compared with the current time. If the heap size reaches three, the employee has used their card three times within the one-hour window and should be flagged. The heap structure keeps timestamps ordered automatically while discarding outdated entries efficiently. This approach is useful in streaming scenarios where events arrive chronologically rather than being processed in batches.

Recommended for interviews: The sliding window with minute conversion is the expected solution. It demonstrates good use of grouping, sorting, and window scanning. A brute-force comparison of every triplet would be inefficient, but the sorted sliding window reduces the check to constant work per element. Interviewers usually look for the insight that only three consecutive timestamps need to be compared after sorting.

Approach 1: Sliding Window Approach with Minute Conversion

This approach involves converting all the given times into minutes from the start of the day (00:00). This simplifies the comparison between times since it reduces the problem to integer comparisons. Once the times are converted, we can use a sliding window to check if there are three occurrences within any 60-minute window.

from collections import defaultdict

def alertNames(keyName, keyTime):
    def getMinutes(t):
        h, m = map(int, t.split(':'))
        return h * 60 + m

    access = defaultdict(list)

    for name, time in zip(keyName, keyTime):
        access[name].append(getMinutes(time))

    alerted = []

    for name, times in access.items():
        times.sort()
        for i in range(len(times) - 2):
            if times[i + 2] - times[i] <= 60:
                alerted.append(name)
                break

    return sorted(alerted)
import java.util.*;

class Solution {
    public List<String> alertNames(String[] keyName, String[] keyTime) {
        Map<String, List<Integer>> accessMap = new HashMap<>();

        for (int i = 0; i < keyName.length; i++) {
            String name = keyName[i];
            String time = keyTime[i];
            int minutes = Integer.parseInt(time.substring(0, 2)) * 60 + Integer.parseInt(time.substring(3));
            accessMap.computeIfAbsent(name, k -> new ArrayList<>()).add(minutes);
        }

        List<String> alerted = new ArrayList<>();
        for (String name : accessMap.keySet()) {
            List<Integer> times = accessMap.get(name);
            Collections.sort(times);

            for (int i = 0; i < times.size() - 2; i++) {
                if (times.get(i + 2) - times.get(i) <= 60) {
                    alerted.add(name);
                    break;
                }
            }
        }

        Collections.sort(alerted);
        return alerted;
    }
}
#include <vector>
#include <string>
#include <unordered_map>
#include <algorithm>

using namespace std;

vector<string> alertNames(vector<string>& keyName, vector<string>& keyTime) {
    unordered_map<string, vector<int>> timesMap;
    
    for (int i = 0; i < keyName.size(); ++i) {
        string time = keyTime[i];
        int minutes = stoi(time.substr(0, 2)) * 60 + stoi(time.substr(3, 2));
        timesMap[keyName[i]].push_back(minutes);
    }
    
    vector<string> result;
    for (auto& [name, times] : timesMap) {
        sort(times.begin(), times.end());
        for (int i = 0; i + 2 < times.size(); ++i) {
            if (times[i + 2] - times[i] <= 60) {
                result.push_back(name);
                break;
            }
        }
    }
    
    sort(result.begin(), result.end());
    return result;
}

This solution uses a dictionary to group all the times by name and convert them to minutes. After that, for each person, it checks if any three consecutive accesses occur within a one-hour (60 minutes) window. We collect all such names and return a sorted list.

Complexity

Time Complexity: O(N log N) where N is the number of entries since we need to sort the times for each person.
Space Complexity: O(N) due to the storage of times in a dictionary.

Try this approach in the editor

Approach 2: Heap-Based Approach

In this approach, we use a heap to keep track of times. As we iterate through each person's access times sorted by minutes, we push each time onto a min-heap and pop times off if they are outside of a rolling window of 60 minutes.

var alertNames = function(keyName, keyTime) {
    const accessMap = {};

    const convertToMinutes = (time) => {
        const [hour, minute] = time.split(':').map(Number);
        return hour * 60 + minute;
    };

    keyName.forEach((name, i) => {
        if (!accessMap[name]) accessMap[name] = [];
        accessMap[name].push(convertToMinutes(keyTime[i]));
    });

    const result = [];
    Object.keys(accessMap).forEach(name => {
        const times = accessMap[name].sort((a, b) => a - b);
        const heap = [];
        for (const time of times) {
            heap.push(time);
            if (heap.length > 3) heap.shift(); // Maintain heap size up to 3
            if (heap.length === 3 && (heap[2] - heap[0]) <= 60) {
                result.push(name);
                break;
            }
        }
    });

    return result.sort();
};
using System;
using System.Collections.Generic;

public class Solution {
    public IList<string> AlertNames(string[] keyName, string[] keyTime) {
        var accessMap = new Dictionary<string, List<int>>();

        int ConvertTimeToMinutes(string time) {
            var parts = time.Split(':');
            return int.Parse(parts[0]) * 60 + int.Parse(parts[1]);
        }

        for (int i = 0; i < keyName.Length; i++) {
            if (!accessMap.ContainsKey(keyName[i]))
                accessMap[keyName[i]] = new List<int>();
            accessMap[keyName[i]].Add(ConvertTimeToMinutes(keyTime[i]));
        }

        List<string> alerted = new List<string>();

        foreach (var entry in accessMap) {
            string name = entry.Key;
            List<int> times = entry.Value;
            times.Sort();

            for (int i = 0; i < times.Count - 2; i++) {
                if (times[i + 2] - times[i] <= 60) {
                    alerted.Add(name);
                    break;
                }
            }
        }

        alerted.Sort();
        return alerted;
    }
}

Here, the JavaScript solution inserts each access time in minutes into a priority queue (heap). For each unique name, it maintains at most the last three access times in sorted order and checks if these fall within a 60-minute window. If they do, we add the name to the results.

Complexity

Time Complexity: O(N log A) where N is the number of logs and A is the average number of accesses per user since sorting and maintaining a heap can be costly.
Space Complexity: O(N) as each log entry needs to be stored.

Try this approach in the editor

Approach 3: Hash Table + Sorting

First, we use a hash table d to record all the clock-in times of each employee.

Then we traverse the hash table. For each employee, we first check whether the number of clock-in times is greater than or equal to 3. If not, we skip this employee. Otherwise, we sort all the clock-in times of this employee in chronological order, and then traverse the sorted clock-in times to check whether the two times at a distance of 2 indices are within the same hour. If so, we add this employee to the answer array.

Finally, we sort the answer array in lexicographical order to get the answer.

The time complexity is O(n times log n), and the space complexity is O(n). Where n is the number of clock-in records.

function alertNames(keyName: string[], keyTime: string[]): string[] {
    const d: { [name: string]: number[] } = {};
    for (let i = 0; i < keyName.length; ++i) {
        const name = keyName[i];
        const t = keyTime[i];
        const minutes = +t.slice(0, 2) * 60 + +t.slice(3);
        if (d[name] === undefined) {
            d[name] = [];
        }
        d[name].push(minutes);
    }
    const ans: string[] = [];
    for (const name in d) {
        if (d.hasOwnProperty(name)) {
            const ts = d[name];
            if (ts.length > 2) {
                ts.sort((a, b) => a - b);
                for (let i = 0; i < ts.length - 2; ++i) {
                    if (ts[i + 2] - ts[i] <= 60) {
                        ans.push(name);
                        break;
                    }
                }
            }
        }
    }
    ans.sort();
    return ans;
}
func alertNames(keyName []string, keyTime []string) (ans []string) {
	d := map[string][]int{}
	for i, name := range keyName {
		var a, b int
		fmt.Sscanf(keyTime[i], "%d:%d", &a, &b)
		t := a*60 + b
		d[name] = append(d[name], t)
	}
	for name, ts := range d {
		n := len(ts)
		if n > 2 {
			sort.Ints(ts)
			for i := 0; i < n-2; i++ {
				if ts[i+2]-ts[i] <= 60 {
					ans = append(ans, name)
					break
				}
			}
		}
	}
	sort.Strings(ans)
	return
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Sliding Window Approach with Minute Conversion

Time Complexity: O(N log N) where N is the number of entries since we need to sort the times for each person.
Space Complexity: O(N) due to the storage of times in a dictionary.

Heap-Based Approach

Time Complexity: O(N log A) where N is the number of logs and A is the average number of accesses per user since sorting and maintaining a heap can be costly.
Space Complexity: O(N) as each log entry needs to be stored.

Hash Table + Sorting–

Complexity analysis

ApproachTimeSpaceWhen to Use
Sliding Window with Minute ConversionO(n log n)O(n)Best general solution. Group times by employee, sort, and check 3-entry windows.
Heap-Based ApproachO(n log n)O(n)Useful when processing access events as a stream and maintaining a rolling 1-hour window.

Frequently asked questions

Is Alert Using Same Key-Card Three or More Times in a One Hour Period easy or hard?

The problem is rated Medium because it combines multiple concepts: time parsing, grouping with a hash map, sorting timestamps, and detecting a sliding window condition. The logic itself is straightforward once timestamps are converted to minutes.

Alert Using Same Key-Card Three or More Times in a One Hour Period Python/Java solution

A typical Python or Java implementation builds a map from employee name to a list of times converted to minutes. After sorting each list, iterate through it and check if the difference between the current time and the one two positions earlier is at most 60 minutes. If true, add the employee to the result set.

How to solve Alert Using Same Key-Card Three or More Times in a One Hour Period in O(n)?

Strict O(n) is difficult because timestamps per employee must be ordered for accurate comparison. After converting times to minutes, sorting the timestamps allows a simple sliding window check across consecutive entries. The resulting complexity is O(n log n), which is considered optimal for this problem.

What is the best approach for Alert Using Same Key-Card Three or More Times in a One Hour Period?

The most efficient solution groups access times by employee, converts each time to minutes, sorts them, and scans using a sliding window. Checking if times[i] - times[i-2] <= 60 detects three accesses within one hour. This approach runs in O(n log n) time due to sorting and uses O(n) space.

Is Alert Using Same Key-Card Three or More Times in a One Hour Period asked at Google/Amazon/Meta?

Problems involving time-window detection, event grouping, and log analysis frequently appear in interviews at companies like Amazon, Google, and Meta. Variants of this question test understanding of sorting, sliding window techniques, and hash-based grouping.

What data structure is used in Alert Using Same Key-Card Three or More Times in a One Hour Period?

The main data structure is a hash map that groups timestamps by employee name. Each employee's timestamps are stored in a list that gets sorted. Some implementations also use heaps to maintain a rolling one-hour window when processing events incrementally.

What is the time complexity of Alert Using Same Key-Card Three or More Times in a One Hour Period?

The optimal solution runs in O(n log n) time. The log factor comes from sorting each employee's access times, while the sliding window scan is linear. Space complexity is O(n) to store grouped timestamps.

Comments

Now write it yourselfClose this page and solve Alert Using Same Key-Card Three or More Times in a One Hour Period in the editor, without looking.
Practise Alert Using Same Key-Card Three or More Times in a One Hour Period