作为在LeetCode网刷题学习时的笔记,为大家学习分享。
题目描述
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6 输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6 输出:[0,1]
提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
- 只会存在一个有效答案
题目解答
1.暴力算法
对于一个数组进行求其中两个数的和,一般会想到遍历两次该数组,求出每一个可能的值去比较。时间复杂度为O(n);
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
int* ans = malloc(sizeof(int)*2);
*returnSize =2;
for(int i=0;i<numsSize-1;i++){
for(int j=i+1;j<numsSize;j++){
if(nums[i]+nums[j] == target){
ans[0] = i;
ans[1] = j;
}
}
}
return ans;
}
2.哈希表查找
这是力扣官方对于哈希表的答案,
struct hashTable* find(int ikey) {
struct hashTable* tmp;
HASH_FIND_INT(hashtable, &ikey, tmp);
return tmp;
}
void insert(int ikey, int ival) {
struct hashTable* it = find(ikey);
if (it == NULL) {
struct hashTable* tmp = malloc(sizeof(struct hashTable));
tmp->key = ikey, tmp->val = ival;
HASH_ADD_INT(hashtable, key, tmp);
} else {
it->val = ival;
}
}
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
hashtable = NULL; // 初始化哈希表
for (int i = 0; i < numsSize; i++) { // 遍历数组
struct hashTable* it = find(target - nums[i]); // 查找target - nums[i]对应的元素
if (it != NULL) { // 如果找到了,说明找到了两个数的和为target
int* ret = malloc(sizeof(int) * 2); // 分配结果数组内存
ret[0] = it->val; // 第一个数是已找到元素的索引(这里假设val存储的是索引)
ret[1] = i; // 第二个数是当前遍历到的元素的索引
*returnSize = 2; // 设置返回数组的大小
return ret; // 返回结果
}
insert(nums[i], i); // 将当前元素及其索引插入哈希表
}
*returnSize = 0; // 如果没有找到符合条件的两个数,则设置返回数组的大小为0
return NULL; // 返回NULL表示没有找到
}
以元素的值作为key存取到哈希表中,实际函数twoSumd的运行可以理解为遍历nums数组的时候,先查找有没有target - nums[i]对应的元素 ,如果有就直接返回两个元素的索引,如果没有,就存到哈希表中,过程实际是边构建哈希表边进行判断。对于答案中的两个宏函数,其实就是对于哈希表的按值查找和元素添加的函数。