Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using array strategy.
You are given a 2D 0-indexed array of strings, access_times, with size n. For each i where 0 <= i <= n - 1, access_times[i][0] represents the name of an employee, and access_times[i][1] represents the access time of that employee. All entries in access_times are within the same day.
The access time is represented as four digits using a 24-hour time format, for example, "0800" or "2250".
An employee is said to be high-access if he has accessed the system three or more times within a one-hour period.
Times with exactly one hour of difference are not considered part of the same one-hour period. For example, "0815" and "0915" are not part of the same one-hour period.
Access times at the start and end of the day are not counted within the same one-hour period. For example, "0005" and "2350" are not part of the same one-hour period.
Return a list that contains the names of high-access employees with any order you want.
Example 1:
Input: access_times = [["a","0549"],["b","0457"],["a","0532"],["a","0621"],["b","0540"]] Output: ["a"] Explanation: "a" has three access times in the one-hour period of [05:32, 06:31] which are 05:32, 05:49, and 06:21. But "b" does not have more than two access times at all. So the answer is ["a"].
Example 2:
Input: access_times = [["d","0002"],["c","0808"],["c","0829"],["e","0215"],["d","1508"],["d","1444"],["d","1410"],["c","0809"]] Output: ["c","d"] Explanation: "c" has three access times in the one-hour period of [08:08, 09:07] which are 08:08, 08:09, and 08:29. "d" has also three access times in the one-hour period of [14:10, 15:09] which are 14:10, 14:44, and 15:08. However, "e" has just one access time, so it can not be in the answer and the final answer is ["c","d"].
Example 3:
Input: access_times = [["cd","1025"],["ab","1025"],["cd","1046"],["cd","1055"],["ab","1124"],["ab","1120"]] Output: ["ab","cd"] Explanation: "ab" has three access times in the one-hour period of [10:25, 11:24] which are 10:25, 11:20, and 11:24. "cd" has also three access times in the one-hour period of [10:25, 11:24] which are 10:25, 10:46, and 10:55. So the answer is ["ab","cd"].
Constraints:
1 <= access_times.length <= 100access_times[i].length == 21 <= access_times[i][0].length <= 10access_times[i][0] consists only of English small letters.access_times[i][1].length == 4access_times[i][1] is in 24-hour time format.access_times[i][1] consists only of '0' to '9'.Problem summary: You are given a 2D 0-indexed array of strings, access_times, with size n. For each i where 0 <= i <= n - 1, access_times[i][0] represents the name of an employee, and access_times[i][1] represents the access time of that employee. All entries in access_times are within the same day. The access time is represented as four digits using a 24-hour time format, for example, "0800" or "2250". An employee is said to be high-access if he has accessed the system three or more times within a one-hour period. Times with exactly one hour of difference are not considered part of the same one-hour period. For example, "0815" and "0915" are not part of the same one-hour period. Access times at the start and end of the day are not counted within the same one-hour period. For example, "0005" and "2350" are not part of the same one-hour period. Return a list that contains the names of high-access
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map
[["a","0549"],["b","0457"],["a","0532"],["a","0621"],["b","0540"]]
[["d","0002"],["c","0808"],["c","0829"],["e","0215"],["d","1508"],["d","1444"],["d","1410"],["c","0809"]]
[["cd","1025"],["ab","1025"],["cd","1046"],["cd","1055"],["ab","1124"],["ab","1120"]]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #2933: High-Access Employees
class Solution {
public List<String> findHighAccessEmployees(List<List<String>> access_times) {
Map<String, List<Integer>> d = new HashMap<>();
for (var e : access_times) {
String name = e.get(0), s = e.get(1);
int t = Integer.valueOf(s.substring(0, 2)) * 60 + Integer.valueOf(s.substring(2));
d.computeIfAbsent(name, k -> new ArrayList<>()).add(t);
}
List<String> ans = new ArrayList<>();
for (var e : d.entrySet()) {
String name = e.getKey();
var ts = e.getValue();
Collections.sort(ts);
for (int i = 2; i < ts.size(); ++i) {
if (ts.get(i) - ts.get(i - 2) < 60) {
ans.add(name);
break;
}
}
}
return ans;
}
}
// Accepted solution for LeetCode #2933: High-Access Employees
func findHighAccessEmployees(access_times [][]string) (ans []string) {
d := map[string][]int{}
for _, e := range access_times {
name, s := e[0], e[1]
h, _ := strconv.Atoi(s[:2])
m, _ := strconv.Atoi(s[2:])
t := h*60 + m
d[name] = append(d[name], t)
}
for name, ts := range d {
sort.Ints(ts)
for i := 2; i < len(ts); i++ {
if ts[i]-ts[i-2] < 60 {
ans = append(ans, name)
break
}
}
}
return
}
# Accepted solution for LeetCode #2933: High-Access Employees
class Solution:
def findHighAccessEmployees(self, access_times: List[List[str]]) -> List[str]:
d = defaultdict(list)
for name, t in access_times:
d[name].append(int(t[:2]) * 60 + int(t[2:]))
ans = []
for name, ts in d.items():
ts.sort()
if any(ts[i] - ts[i - 2] < 60 for i in range(2, len(ts))):
ans.append(name)
return ans
// Accepted solution for LeetCode #2933: High-Access Employees
// Rust example auto-generated from java reference.
// Replace the signature and local types with the exact LeetCode harness for this problem.
impl Solution {
pub fn rust_example() {
// Port the logic from the reference block below.
}
}
// Reference (java):
// // Accepted solution for LeetCode #2933: High-Access Employees
// class Solution {
// public List<String> findHighAccessEmployees(List<List<String>> access_times) {
// Map<String, List<Integer>> d = new HashMap<>();
// for (var e : access_times) {
// String name = e.get(0), s = e.get(1);
// int t = Integer.valueOf(s.substring(0, 2)) * 60 + Integer.valueOf(s.substring(2));
// d.computeIfAbsent(name, k -> new ArrayList<>()).add(t);
// }
// List<String> ans = new ArrayList<>();
// for (var e : d.entrySet()) {
// String name = e.getKey();
// var ts = e.getValue();
// Collections.sort(ts);
// for (int i = 2; i < ts.size(); ++i) {
// if (ts.get(i) - ts.get(i - 2) < 60) {
// ans.add(name);
// break;
// }
// }
// }
// return ans;
// }
// }
// Accepted solution for LeetCode #2933: High-Access Employees
function findHighAccessEmployees(access_times: string[][]): string[] {
const d: Map<string, number[]> = new Map();
for (const [name, s] of access_times) {
const h = parseInt(s.slice(0, 2), 10);
const m = parseInt(s.slice(2), 10);
const t = h * 60 + m;
if (!d.has(name)) {
d.set(name, []);
}
d.get(name)!.push(t);
}
const ans: string[] = [];
for (const [name, ts] of d) {
ts.sort((a, b) => a - b);
for (let i = 2; i < ts.length; ++i) {
if (ts[i] - ts[i - 2] < 60) {
ans.push(name);
break;
}
}
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.