98 lines
2.4 KiB
C
98 lines
2.4 KiB
C
#include <stdlib.h>
|
|
|
|
typedef struct {
|
|
int key, value;
|
|
} HashMapEntry;
|
|
|
|
typedef struct {
|
|
int size;
|
|
HashMapEntry **entries;
|
|
} HashMap;
|
|
|
|
HashMap *makeHashMap(int size) {
|
|
HashMap *m = malloc(sizeof(HashMap));
|
|
m->size = size;
|
|
m->entries = malloc(size * sizeof(HashMapEntry*));
|
|
for (int i = 0; i < size; i++) {
|
|
m->entries[i] = NULL;
|
|
}
|
|
return m;
|
|
}
|
|
|
|
int hashCode(HashMap *m, int key) {
|
|
return ((unsigned int) key * 2654435761U) % m->size;
|
|
}
|
|
|
|
HashMapEntry *makeEntry(int key, int value) {
|
|
HashMapEntry *e = malloc(sizeof(HashMapEntry));
|
|
e->key = key;
|
|
e->value = value;
|
|
return e;
|
|
}
|
|
|
|
#define PUT_SUCCESS 1
|
|
#define PUT_FAIL 0
|
|
|
|
int putAt(HashMap *m, HashMapEntry *e, int index) {
|
|
if (m->entries[index] == NULL) {
|
|
m->entries[index] = e;
|
|
return PUT_SUCCESS;
|
|
}
|
|
return PUT_FAIL;
|
|
}
|
|
|
|
int put(HashMap *m, int key, int value) {
|
|
int hash = hashCode(m, key);
|
|
HashMapEntry *e = makeEntry(key, value);
|
|
for (int i = hash; i < m->size; i++) {
|
|
if (putAt(m, e, i)) return PUT_SUCCESS;
|
|
}
|
|
for (int i = 0; i < hash; i++) {
|
|
if (putAt(m, e,i)) return PUT_SUCCESS;
|
|
}
|
|
return PUT_FAIL;
|
|
}
|
|
|
|
HashMapEntry *get(HashMap *m, int key) {
|
|
int hash = hashCode(m, key);
|
|
for (int i = hash; i < m->size; i++) {
|
|
if (m->entries[i] != NULL) {
|
|
HashMapEntry *e = m->entries[i];
|
|
if (e->key == key) {
|
|
return e;
|
|
}
|
|
}
|
|
}
|
|
for (int i = 0; i < hash; i++) {
|
|
if (m->entries[i] != NULL) {
|
|
HashMapEntry *e = m->entries[i];
|
|
if (e->key == key) {
|
|
return e;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Note: The returned array must be malloced, assume caller calls free().
|
|
*/
|
|
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
|
|
HashMap *m = makeHashMap(numsSize / 0.7);
|
|
for (int i = 0; i < numsSize; i++) {
|
|
int complement = target - nums[i];
|
|
HashMapEntry *e = get(m, complement);
|
|
if (e != NULL && e->value != i) {
|
|
int *result = malloc(2 * sizeof(int));
|
|
result[0] = i;
|
|
result[1] = e->value;
|
|
*returnSize = 2;
|
|
return result;
|
|
} else if (!put(m, nums[i], i)) {
|
|
*returnSize = 0;
|
|
return malloc(0); // fail
|
|
}
|
|
}
|
|
*returnSize = 0;
|
|
return malloc(0);
|
|
} |