-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy path049-Anagrams.c
113 lines (106 loc) · 3.04 KB
/
049-Anagrams.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
struct I2iHashNode {
int key;
int value;
struct I2iHashNode* next;
};
struct I2iHashTable {
struct I2iHashNode** buckets;
int bucketSize;
};
struct I2iHashTable* hashmap_create(int size) {
struct I2iHashTable * table = malloc(sizeof(struct I2iHashTable));
table->bucketSize = size;
table->buckets = malloc(sizeof(struct I2iHashTable *) * size);
memset(table->buckets, 0, sizeof(struct I2iHashTable *) * size);
return table;
}
struct I2iHashNode* hashmap_get(struct I2iHashTable* table, int key) {
int hash = key % table->bucketSize;
while (hash < 0) hash += table->bucketSize;
struct I2iHashNode* node = table->buckets[hash];
while(node != NULL && node->key <= key) {
if(node->key == key) {
return node;
}
node = node->next;
}
return NULL;
}
void hashmap_set(struct I2iHashTable* table, int key, int value) {
int hash = key % table->bucketSize;
while (hash < 0) hash += table->bucketSize;
struct I2iHashNode* node = table->buckets[hash];
if (node == NULL || node->key > key) {
struct I2iHashNode * tmp = malloc(sizeof(struct I2iHashNode));
tmp->key = key;
tmp->value = value;
tmp->next = node; // node != NULL ? node : NULL
table->buckets[hash] = tmp;
return;
}
if (node->key == key) {
node->value = value;
return;
}
while (node->next != NULL && node->next->key < key) {
node = node->next;
}
if (node->next != NULL && node->next->key == key) {
node->next->value = value;
return;
}
struct I2iHashNode * tmp = malloc(sizeof(struct I2iHashNode));
tmp->key = key;
tmp->value = value;
tmp->next = node->next;
node->next = tmp;
}
int hashAnagram(char* s) {
unsigned int h1 = 378551;
unsigned int h2 = 63689;
int a[26];
memset(a, 0, sizeof(int)*26);
while (*s != '\0') {
a[*s-'a']++;
s++;
}
unsigned int i, j, hash = 1;
for (i = 0 ; i < 26 ; i++) {
if (a[i] > 0) {
for (j = 0 ; j < a[i] ; j++) {
hash *= h2;
hash += i+1;
}
}
h2 *= h1;
}
return hash & 0x7FFFFFFF;
}
char** anagrams(char** strs, int strsSize, int* returnSize) {
char** res = malloc(sizeof(char*) * 10000);
(* returnSize) = 0;
struct I2iHashTable* table = hashmap_create(strsSize);
int i;
for (i = 0 ; i < strsSize ; i++) {
int hash = hashAnagram(strs[i]);
struct I2iHashNode * node = hashmap_get(table, hash);
if (node != NULL) {
if (node->value >= 0) {
int l = strlen(strs[node->value]);
res[(* returnSize)] = malloc(l+1);
memcpy(res[(* returnSize)++], strs[node->value], l+1);
node->value = -1;
}
int l = strlen(strs[i]);
res[(* returnSize)] = malloc(l+1);
memcpy(res[(* returnSize)++], strs[i], l+1);
} else {
hashmap_set(table, hash, i);
}
}
return res;
}