思路
题目意思
这题有两个数组 keyName 和 keyTime 分别代表员工名字和员工一天内刷卡的时间,让你找有多少员工一小时内出现三次即以上的刷卡记录
,则会收到系统警告,我们需要把系统警告到员工数组 字典序升序
排序后返回
方法:哈希表 + 快排
看到这题我的第一想法是哈希表记录每个员工一天的刷卡时间数组,再用滑动窗口判断是否出现一小时内出现三次即以上的刷卡记录
,但是题目并没有给出数据是按照升序或者降序出来的,所以我们需要在做一步排序操作。
仔细思考其实不需要滑动窗口,因为他不需要统计一个小时出现了多少次刷卡记录,所以我们排序后,只需要判断 v[i] 与 v[i+2](v数组指某个员工的一天刷卡记录升序排序后的数组)相减是否小于等于 60 即可。
代码示例
func alertNames(keyName []string, keyTime []string) (ans []string) {
mp := make(map[string][]int)
for i := range keyName {
// 将 HH:MM 换算成时间戳
mp[keyName[i]] = append(mp[keyName[i]], (int(keyTime[i][0] - '0') * 10 + int(keyTime[i][1] - '0')) * 60 + (int(keyTime[i][3] - '0') * 10 + int(keyTime[i][4] - '0')))
}
for k, v := range mp {
// sort包语法糖快排
sort.Ints(v)
for i := 0; i < len(v) - 2; i++ {
if v[i + 2] - v[i] <= 60 {
ans = append(ans, k)
break
}
}
}
sort.Strings(ans)
return ans
}
复杂度分析
-
时间复杂度:O(nlogn),其中 n 是数组 keyName 和 keyTime 的长度。 需要遍历数组 keyName 和 keyTime,得到每个员工的全部使用员工卡的时间,遍历的时间复杂度是 O(n),存入哈希表的时间复杂度是 O(1),因此时间复杂度是 O(n)。 然后判断每个员工是否收到系统警告,需要进行排序和遍历的操作,最坏情况下,排序的时间复杂度是 O(nlogn),遍历的时间复杂度是 O(n),因此时间复杂度是 O(nlogn)。 因此总时间复杂度是 O(nlogn)。
-
空间复杂度:O(n),其中 n 是数组 keyName 和 keyTime 的长度。空间复杂度主要取决于哈希表,需要存储所有员工的全部打卡时间。