我们知道,C语言里面是没有hash表的,但是我们可以用一个结构体表示,对结构体排序,我们可以用qsort排序。
下面我们用一个LeedCode上面的一道题目讲解。
347. 前 K 个高频元素
这个题目是让我们求解前k个高频元素,求解思路如下:我们构建一个Hash表,Hash表用一个结构体表示,该结构体存放元素值和元素的个数,我们先把数组里面的值存放到Hash表里面,然后我们对该Hash表按照元素个数进行进行排序,这样就可以找到前k个高频元素了。
1 定义Hash表
#define Hash_SIZE 20001
#define OFFSET 10000 typedef struct {int val; //存放值int cnt; //cnt存储出现次数
}HashTable;
HashTable hash[Hash_SIZE];
hash就是我们要的Hash表。
2 将数组值存放到Hash表中
for (i = 0; i < numsSize; i++) { //将值和出现的次数放入hash表中hash[(nums[i] + OFFSET) % Hash_SIZE].cnt++; //偏移使下标>=0hash[(nums[i] + OFFSET) % Hash_SIZE].val = nums[i];}for (i = 0; i < Hash_SIZE; i++) { //对原hash表进行优化,从开始存储if (hash[i].cnt != 0) {hash[j].cnt = hash[i].cnt;hash[j].val = hash[i].val;j++;}}
3 对Hash表按照元素个数进行排序
int comp(const void* a, const void* b) { //cnt大到小return (((HashTable*)b)->cnt - ((HashTable*)a)->cnt);
}qsort(hash, j, sizeof(HashTable), comp);
全部代码:
#define Hash_SIZE 20001
#define OFFSET 10000 typedef struct {int val;int cnt; //cnt存储出现次数
}HashTable;
HashTable hash[Hash_SIZE];int comp(const void* a, const void* b) { //cnt大到小return (((HashTable*)b)->cnt - ((HashTable*)a)->cnt);
}int* topKFrequent(int* nums, int numsSize, int k, int* returnSize) {memset(hash, 0, sizeof(hash)); //初始化0int i, j = 0;for (i = 0; i < numsSize; i++) { //将值和出现的次数放入hash表中hash[(nums[i] + OFFSET) % Hash_SIZE].cnt++; //偏移使下标>=0hash[(nums[i] + OFFSET) % Hash_SIZE].val = nums[i];}for (i = 0; i < Hash_SIZE; i++) { //对原hash表进行优化,从开始存储if (hash[i].cnt != 0) {hash[j].cnt = hash[i].cnt;hash[j].val = hash[i].val;j++;}}qsort(hash, j, sizeof(HashTable), comp);for (i = 0; i < k; i++) nums[i] = hash[i].val; //输出前k个高频元素*returnSize = k;return nums;
}
其他
为什么OFFSET是10000,Hash_Size是20001,我看别人的解释是这个题目数的范围是-10000到+10000。超过这个范围会报错