(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。