(LeetCode刷题)1. 两数之和
题目

解答一:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
for (int i = 0; i < numsSize; ++i) {
for (int j = i + 1; j < numsSize; ++j) {
if (nums[i] + nums[j] == target) {
*returnSize = 2;
int* res = (int*)malloc(sizeof(int) * (*returnSize));
res[0] = i;
res[1] = j;
return res;
}
}
}
*returnSize = 0;
return NULL;
}非常简单的思路,使用两层循环对数组内的数进行两两相加,然后同target相比较。时间复杂度为O(n²)。

解答二:
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
int* ret = (int*)malloc(sizeof(int) * 2);
*returnSize = 2;
int hash[20011] = {0};
for (int i = 0; i < numsSize; ++i) {
long complement = target - nums[i];
int index = ((complement + (long)1e9) % 20011);
index = index < 0 ? index + 20011 : index; // ensure the index is positive
if (hash[index]) {
ret[0] = hash[index] - 1;
ret[1] = i;
return ret;
}
index = ((nums[i] + (long)1e9) % 20011); // similarly for nums[i]
index = index < 0 ? index + 20011 : index;
hash[index] = i + 1;
}
*returnSize = 0;
return NULL;
}此C函数首先创建一个大小为2的动态整形数组ret。然后,创建了大小为20011的哈希表,用于散列所有可能的输入。
然后,该函数遍历输入数组nums的每个元素。对于每个元素nums[i],首先计算其与目标数值的差值complement。然后,将差值加上后对20011取模得到哈希表的索引。取模是为了将任何在-到范围内的整数映射到一个正数索引。如果取模结果为负,为防止数组越界,需要加上模数以使得索引变为正数。
接下来,判断哈希表中该索引位置是否已有元素。如果有,说明找到了匹配项,将哈希表索引对应元素以及当前值所在的索引退回。接下来对nums[i]执行相等操作并存储到哈希表中,这是为了让后面的元素找到和为目标值的组合。
最后,如果在数组中没有找到匹配项,则将返回值的大小设为0,并返回NULL。




