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.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for this problem is like checking every possible combination of key-card uses to see if anyone triggered an alert. We will systematically explore all the options to find those who used their card multiple times within an hour. It's like manually going through security logs to find suspicious patterns.
Here's how the algorithm would work step-by-step:
def find_alert_employees(key_card_records):
alert_employees = []
# Group key card records by employee.
employee_records = {}
for employee_name, time in key_card_records:
if employee_name not in employee_records:
employee_records[employee_name] = []
employee_records[employee_name].append(time)
for employee_name, times in employee_records.items():
times.sort()
employee_triggered_alert = False
# Iterate through all possible groups of three or more times.
for i in range(len(times) - 2):
for j in range(i + 2, len(times)):
# Check if all key-card uses occurred within a one-hour period.
if times[j] - times[i] <= 60:
# Flag if employee triggered alert.
employee_triggered_alert = True
break
if employee_triggered_alert:
break
if employee_triggered_alert:
alert_employees.append(employee_name)
return sorted(alert_employees)
def alert_using_same_key_card(
key_card_names,
key_card_times
):
key_card_records = list(zip(key_card_names, key_card_times))
return find_alert_employees(key_card_records)
The problem requires us to identify employees who use their key-cards excessively within a one-hour window. To do this efficiently, we need to organize the data and then focus on analyzing each employee's access times individually to find potential violations.
Here's how the algorithm would work step-by-step:
def alert_names(key_name, key_time):
employee_to_times = {}
for i in range(len(key_name)):
employee = key_name[i]
time = int(key_time[i])
if employee not in employee_to_times:
employee_to_times[employee] = []
employee_to_times[employee].append(time)
alerted_employees = []
# Iterate through each employee's access times.
for employee, times in employee_to_times.items():
times.sort()
for i in range(len(times) - 2):
# Check if at least 3 accesses happen within an hour.
if times[i + 2] - times[i] <= 60:
# Add to alert list, only if not already there.
if employee not in alerted_employees:
alerted_employees.append(employee)
# Sort the alerted names alphabetically.
alerted_employees.sort()
return alerted_employees
Case | How to Handle |
---|---|
keyName or keyTime is null or empty | Return an empty list if either input is null or empty, as there are no employees or times to process. |
keyName and keyTime have different lengths | Throw an IllegalArgumentException or return an empty list, because the input is invalid. |
Input with only one or two entries for a single employee | No employee can trigger the alert condition; so return an empty list if no employee has at least three entries. |
Large input size, potentially exceeding memory limits if not handled efficiently. | Use a hash map and sort only the times for each employee, avoiding sorting the entire input at once, for better space complexity. |
All access times for an employee are identical | The algorithm should correctly identify the employee as an alert case if there are three or more identical times within the one-hour window. |
Access times are not in chronological order within each employee's access records | Sort the access times for each employee to correctly identify accesses within a one-hour period. |
Invalid time format (e.g., HH > 23, MM > 59, or non-numeric characters). | Validate the time format and throw an exception or skip the entry if invalid. |
Multiple alert employees exist. | The algorithm should correctly identify and return a sorted list of all alert employees. |