使用小型哈希表解决C语言中的“两数之和”
在计算机科学中,“哈希表”是一种十分重要的数据结构。通过哈希表,我们可以以常数时间进行插入,查找和删除操作。而在C语言中,我们可以使用小型哈希表来解决一个经典的问题:“两数之和”。
这个问题的描述非常简单:给定一个整数数组和一个目标整数,在数组中找到两个数,它们的和等于目标整数,并返回它们的下标。我们可以使用一种暴力搜索的方法来解决这个问题,但是这种方法的时间复杂度是O(n^2),不是很高效。
而使用哈希表,我们可以将时间复杂度降到O(n)。具体来说,我们可以遍历一次整个数组,将每个数字插入哈希表中。每插入一个数字,我们就检查哈希表中是否存在一个与它相加等于目标整数的数。如果存在,则我们成功地找到了两数之和,并返回它们的下标。
下面是一个使用C语言编写的小型哈希表解决“两数之和”的示例代码:
“`
#include
#include
#include
typedef struct hash_node {
int key;
int value;
struct hash_node *next;
} hash_node_t;
typedef struct hash_map {
int size;
hash_node_t **buckets;
} hash_map_t;
hash_map_t *hash_map_create(int size) {
hash_map_t *map = malloc(sizeof(hash_map_t));
map->size = size;
map->buckets = calloc(size, sizeof(hash_node_t *));
return map;
}
int hash_map_hash(int key, int size) {
return abs(key) % size;
}
void hash_map_insert(hash_map_t *map, int key, int value) {
int hash = hash_map_hash(key, map->size);
hash_node_t *node = malloc(sizeof(hash_node_t));
node->key = key;
node->value = value;
node->next = map->buckets[hash];
map->buckets[hash] = node;
}
bool hash_map_contains(hash_map_t *map, int key) {
int hash = hash_map_hash(key, map->size);
hash_node_t *node = map->buckets[hash];
while (node != NULL) {
if (node->key == key) {
return true;
}
node = node->next;
}
return false;
}
void hash_map_destroy(hash_map_t *map) {
for (int i = 0; i < map->size; i++) {
hash_node_t *node = map->buckets[i];
while (node != NULL) {
hash_node_t *temp = node;
node = node->next;
free(temp);
}
}
free(map->buckets);
free(map);
}
int *two_sum(int *nums, int numsSize, int target) {
hash_map_t *map = hash_map_create(numsSize);
for (int i = 0; i < numsSize; i++) {
int complement = target – nums[i];
if (hash_map_contains(map, complement)) {
int *result = malloc(2 * sizeof(int));
result[0] = i;
result[1] = hash_map_hash(complement, map->size);
hash_map_destroy(map);
return result;
}
hash_map_insert(map, nums[i], i);
}
hash_map_destroy(map);
return NULL;
}
int main() {
int nums[] = {2, 7, 11, 15};
int target = 9;
int *result = two_sum(nums, 4, target);
printf(“[%d, %d]\n”, result[0], result[1]);
free(result);
return 0;
}
“`
在上面的代码中,我们首先定义了哈希表(结构体`hash_map`)和哈希节点(结构体`hash_node`)。哈希表包含一个`size`属性和一个`buckets`属性,`buckets`是一个指向哈希节点指针的数组。哈希节点包含一个`key`属性和一个`value`属性,`key`存储整数,在“两数之和”问题中就是数组中的数字,`value`也存储整数,在“两数之和”问题中就是数字在数组中的下标。
我们使用`hash_map_create`函数创建一个哈希表,使用`hash_map_hash`函数计算哈希值,使用`hash_map_insert`函数将一个键值对插入哈希表中,使用`hash_map_contains`函数检查哈希表中是否存在某个键。
最后,在`two_sum`函数中我们遍历整个数组,每次都检查是否存在一个与当前数字相加等于目标整数的数字。如果存在,则返回这两个数字在数组中的下标。
使用哈希表可以大大提高“两数之和”问题的解决效率,是一种非常有用的数据结构和算法。如果你想深入学习哈希表及其应用,请参考本文开头给出的链接。
了解更多有趣的事情:https://blog.ds3783.com/