-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
Copy path0347-Top-K-Frequent-Elements.c
86 lines (75 loc) · 3.09 KB
/
0347-Top-K-Frequent-Elements.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#define ALLOCATION_SIZE 100 // Allocation size of the numsArrLen in frequencyArrItem
typedef struct hash_entry {
int num; /* we'll use this field as the key */
int count;
UT_hash_handle hh; /* makes this structure hashable */
}hash_entry;
typedef struct frequencyArrItem
{
int* numsArr;
int numsArrLen;
int index; // Points to the first empty space in numsArr
}frequencyArrItem;
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* topKFrequent(int* nums, int numsSize, int k, int* returnSize){
int* result = (int*)malloc(k * sizeof(int));
*returnSize = k;
int resultIndex = 0; // Points to the first empty space in result
hash_entry* NumFreqMap = NULL;
frequencyArrItem frequencyArr[numsSize + 1]; // Index is the count/frequency and the element is an array of numbers with this frequency
memset(frequencyArr, 0, (numsSize + 1) * sizeof(frequencyArrItem)); // Initialize with NULL and zeros
for(int i = 0; i < numsSize; i++)
{
hash_entry* retrievedMapEntry;
HASH_FIND_INT(NumFreqMap, &nums[i], retrievedMapEntry);
// If the number already exists in the map then increment its count
if(retrievedMapEntry)
{
retrievedMapEntry->count += 1;
}
else
{
// If the number doesn't exist in the map then create a new map entry for it and add it to the map
hash_entry* mapEntryToAdd = (hash_entry*)malloc(sizeof(hash_entry));
mapEntryToAdd->num = nums[i];
mapEntryToAdd->count = 1;
HASH_ADD_INT(NumFreqMap, num, mapEntryToAdd);
}
}
// Loop over all the entries in the hash map
for (hash_entry* mapEntry = NumFreqMap; mapEntry != NULL; mapEntry = mapEntry->hh.next) {
frequencyArrItem* freq = frequencyArr + mapEntry->count;
// If the nums list for this frequency has not been created yet
if(freq->numsArrLen == 0)
{
freq->numsArrLen = ALLOCATION_SIZE;
freq->numsArr = (int*)malloc(freq->numsArrLen * sizeof(int));
}
// If the nums list exceeded the current allocated size, then reallocate
else if(freq->index == freq->numsArrLen)
{
freq->numsArrLen += ALLOCATION_SIZE;
freq->numsArr = (int*)realloc(freq->numsArr, freq->numsArrLen * sizeof(int));
}
freq->numsArr[freq->index++] = mapEntry->num;
}
// Loop over the frequencies starting from the highest frequency
for(int i = numsSize; i >= 1; i--) // Note that we are looping until i == 1, as at index 0 it is just empty
{
frequencyArrItem* freq = frequencyArr + i;
// If there is nums that exist at this particular frequency
for(int j = 0; j < freq->index; j++)
{
// If we have added all the elements we need to the result
if(k-- == 0)
{
return result;
}
// Add the num to the result then increment the index
result[resultIndex++] = freq->numsArr[j];
}
}
return result;
}