📅  最后修改于: 2023-12-03 15:13:47.346000             🧑  作者: Mango
给定一个整数数组和一个目标值,找到数组中和为目标值的两个数。
可以假设每个输入都只有一个答案,并且不能使用同一个元素两次。
int nums[] = {2, 7, 11, 15};
int target = 9;
int *result = twoSum(nums, sizeof(nums)/sizeof(int), target);
// result 将指向 [0, 1] 的数组
我们可以使用哈希表来解决这个问题。
首先,我们使用一个哈希表来存储每个数字在数组中的索引。然后,我们遍历数组中的每个数字,在哈希表中查找是否存在一个数字满足 target - nums[i]
的条件。
如果找到了这样的数字,我们就可以返回它们的索引了。
int* twoSum(int* nums, int numsSize, int target) {
int* result = (int*)malloc(sizeof(int)*2);
if (result == NULL) {
return NULL;
}
memset(result, 0, sizeof(int)*2);
int i;
int complement;
// 创建哈希表
int hashSize = numsSize * 2;
struct HashNode** hashTable = (struct HashNode**)malloc(sizeof(struct HashNode*)*hashSize);
if (hashTable == NULL) {
free(result);
return NULL;
}
memset(hashTable, 0, sizeof(struct HashNode*)*hashSize);
// 遍历数组
for (i = 0; i < numsSize; i++) {
complement = target - nums[i];
int hashIndex = hash(complement, hashSize);
struct HashNode* node = hashTable[hashIndex];
// 在哈希表中查找
while (node != NULL) {
if (node->key == complement) {
result[0] = node->value;
result[1] = i;
goto end;
}
node = node->next;
}
// 在哈希表中添加当前数字的索引
struct HashNode* newNode = (struct HashNode*)malloc(sizeof(struct HashNode));
if (newNode == NULL) {
freeHashTable(hashTable, hashSize);
free(result);
return NULL;
}
newNode->key = nums[i];
newNode->value = i;
newNode->next = hashTable[hashIndex];
hashTable[hashIndex] = newNode;
}
end:
freeHashTable(hashTable, hashSize);
return result;
}
// 哈希表节点
struct HashNode {
int key;
int value;
struct HashNode* next;
};
// 哈希函数
int hash(int key, int hashSize) {
return key % hashSize;
}
// 释放哈希表
void freeHashTable(struct HashNode** hashTable, int hashSize) {
int i;
for (i = 0; i < hashSize; i++) {
struct HashNode* node = hashTable[i];
while (node != NULL) {
struct HashNode* temp = node;
node = node->next;
free(temp);
}
}
free(hashTable);
}
该问题可以使用哈希表以 $O(n)$ 时间复杂度解决。
我们可以遍历数组,对于每个数字,我们可以使用哈希表来查找是否存在一个数字满足 target - nums[i]
的条件。
如果找到了这样的数字,我们只需要返回它们的索引即可。
这个问题的关键是如何使用哈希表来提高查找效率。我们可以在遍历数组的同时,查找哈希表中是否存在满足条件的数字,同时,将当前数字的索引添加到哈希表中。
这样,就可以实现 $O(n)$ 的时间复杂度。
完整代码和注释可以在 GitHub 上查看。