#include typedef struct { int key, value; } HashMapEntry; typedef struct EntryList { HashMapEntry *entry; struct EntryList *next; } EntryList; typedef struct { int size; EntryList **entries; } HashMap; HashMap *makeHashMap(int size) { HashMap *m = malloc(sizeof(HashMap)); m->size = size; m->entries = malloc(size * sizeof(EntryList *)); 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; } EntryList *makeLinkedList(HashMapEntry *e) { EntryList *l = malloc(sizeof(EntryList)); l->entry = e; l->next = NULL; return l; } void appendEntryList(EntryList *l, HashMapEntry *e) { while (l->next != NULL) l = l->next; l->next = makeLinkedList(e); } void putAt(HashMap *m, HashMapEntry *e, int index) { if (m->entries[index] == NULL) { m->entries[index] = makeLinkedList(e); } else { appendEntryList(m->entries[index], e); } } void put(HashMap *m, int key, int value) { int hash = hashCode(m, key); HashMapEntry *e = makeEntry(key, value); putAt(m, e, hash); } HashMapEntry *get(HashMap *m, int key) { int hash = hashCode(m, key); EntryList *l = m->entries[hash]; while (l != NULL && l->entry->key != key) { l = l->next; } if (l == NULL) return NULL; return l->entry; } void freeEntryList(EntryList *l) { int size = 0; EntryList *current = l; while (current != NULL) { current = current->next; size++; } EntryList **reversed = malloc(size * sizeof(EntryList *)); current = l; for (int i = 0; i < size; i++) { reversed[size - i - 1] = current; current = current->next; } for (int i = 0; i < size; i++) { free(reversed[i]->entry); free(reversed[i]); } free(reversed); } void freeHashMap(HashMap *m) { for (int i = 0; i < m->size; i++) { freeEntryList(m->entries[i]); } free(m->entries); free(m); } /** * 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; freeHashMap(m); return result; } else { put(m, nums[i], i); } } freeHashMap(m); *returnSize = 0; return malloc(0); }