作者:小迅
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目
示例
思路
题意 -> 给定一些时间节点和对应的人名,请按字典序排列返回 时间节点 在 一个小时内出现 三次 的人名
由于给定的数组是每个员工在同一天内使用员工卡的时间,因此同一个员工使用员工卡的时间顺序一定是按照小时数和分钟数递增的。只要获得每个员工的全部使用员工卡的时间,即可判断哪些员工收到系统警告,即哪些员工在一小时内使用员工卡的次数大于等于三次。
对于员工和对应时间节点的关系处理 :
使用哈希表记录并存储所以员工对应的时间节点,方便后序比较是否在一个小时之内出现三次
对于时间节点的处理:
由于一个员工存在很多时间节点,所以优先考虑使用数组对时间节点进行统一管理,但是在对每一个时间节点记录时就会涉及插入操作,所以将数组改为链表更方便操作
由于给出的时间为 24小时制 ,形如 "HH:MM" ,不利于直观的比较和排序,因此将时间统一改为 分秒制,再后序中只需要将一个员工的时间进行升序排列,并将两个时间相减即可得出是否在一个小时之内
对于哈希表的操作,力扣是支持库的,哈希库接口详解
代码
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
typedef struct {
char *key; /* key */
struct ListNode *val;
UT_hash_handle hh; /* makes this structure hashable */
}HashItem;
struct ListNode *creatListNode(int val) {//链表初始化
struct ListNode *obj = (struct ListNode *)malloc(sizeof(struct ListNode));
obj->val = val;
obj->next = NULL;
return obj;
}
void freeList(struct ListNode *list) {//链表销毁
while (list) {
struct ListNode *curr = list;
list = list->next;
free(curr);
}
}
static int cmp1(const void *pa, const void *pb) {//时间节点排序
return *(int *)pa - *(int *)pb;
}
static int cmp2(const void *pa, const void *pb) {//人名字典序排序
return strcmp(*(char **)pa, *(char **)pb);
}
char ** alertNames(char ** keyName, int keyNameSize, char ** keyTime, int keyTimeSize, int* returnSize) {
HashItem *timeMap = NULL;
for (int i = 0; i < keyNameSize; i++) {//入哈希表
char *name = keyName[i];
char *time = keyTime[i];
int hour = (time[0] - '0') * 10 + (time[1] - '0');
int minute = (time[3] - '0') * 10 + (time[4] - '0');
HashItem *s = NULL;
HASH_FIND_STR(timeMap, name, s);//查询是否在哈希表中存在
if (!s) {//不存在,创建并加入哈希表
s = (HashItem *)malloc(sizeof(HashItem));
s->key = name;
s->val = NULL;
HASH_ADD_STR(timeMap, key, s);
}
//不管存不存在肯定需要将时间节点加入对应的员工下
struct ListNode *node = creatListNode(hour * 60 + minute);
node->next = s->val;
s->val = node;
}
//保存有效员工名单
char **res = (char **)malloc(sizeof(char *) * keyNameSize);
int pos = 0;
HashItem *curr = NULL, *temp = NULL;
int arr[keyNameSize];//将链表转为数组,更方便排序操作
HASH_ITER(hh, timeMap, curr, temp) {
int size = 0;
for (struct ListNode *node = curr->val; node; node = node->next) {//链表转数组
arr[size++] = node->val;
}
qsort(arr, size, sizeof(int), cmp1);//排序
for (int i = 2; i < size; i++) {
//因为已经升序了,中间元素必然满足要求
int time1 = arr[i - 2], time2 = arr[i];
int difference = time2 - time1;//比较三个元素
if (difference <= 60) {//满足题目要求
res[pos] = (char *)malloc(sizeof(char) * (strlen(curr->key) + 1));
strcpy(res[pos], curr->key);
pos++;
break;
}
}
}
qsort(res, pos, sizeof(char *), cmp2);//员工排序
*returnSize = pos;
/* free the hash table contents */
HASH_ITER(hh, timeMap, curr, temp) {//销毁整个哈希表
HASH_DEL(timeMap, curr);
freeList(curr->val);
free(curr);
}
return res;
}
作者:小迅
链接:https://leetcode.cn/problems/alert-using-same-key-card-three-or-more-times-in-a-one-hour-period/solutions/2097833/ha-xi-zhu-shi-chao-ji-xiang-xi-by-xun-ge-djtp/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。