1. 两数之和
给定一个整数数组 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
- 只会存在一个有效答案
进阶:你可以想出一个时间复杂度小于 O(n2)
的算法吗?
2.解题思路
首先,我们需要了解题目中给定的条件:
nums
是一个整数数组,长度为n
,其中n > 1
。target
是一个整数,需要在nums
数组中找出两个数的和等于target
。- 返回这两个数的下标,下标从
0
开始计数,下标可以是重复的,但数字不能重复。基于这些条件,我们可以使用哈希表的方法来解决问题。具体来说,我们可以使用一个 hashtable 来存储
nums
数组中的数字和下标,然后从头开始遍历nums
数组,对于当前数字nums[i]
,我们计算target - nums[i]
,在 hashtable 中查找是否存在这个数,如果存在,则返回这两个数的下标,如果不存在,插入哈希表中以便下次查找。
首先创建一个哈希表:
// 定义哈希表的结构体
struct hashTable{
int key;
int value;
UT_hash_handle hh; // UT_hash_handle是<hash.h>中定义的一个结构体
} ;
struct hashTable* hashtable;
UT_hash_handle
是在<hash.h>
中定义的一个结构体,它用于在哈希表中存储元素的元数据,以便实现哈希表的操作。UT_hash_handle
结构体的定义如下:
struct UT_hash_handle {
void *prev;
void *next;
UT_hash_handle *hh;
};
在 hashTable结构体中,使用
UT_hash_handle hh;
来声明一个UT_hash_handle
类型的变量,用于在哈希表中存储节点的元数据。
在哈希表中查找元素:
struct hashTable* find(int ikey) {
struct hashTable* tmp;
HASH_FIND_INT(hashtable, &ikey, tmp);
return tmp;
}
HASH_FIND_INT
是 C 标准库中<hash.h>
头文件定义的一个宏,它用于在哈希表中查找一个键值对。如果找到了键值对,它将返回键的值,否则返回NULL
。
在哈希表中插入元素
// 定义函数insert,它接受一个整数key和一个整数val,表示要插入的键值对
void insert(int ikey, int ival)
{
// 在哈希表中查找key
struct hashTable* it=find(ikey);
// 如果没有找到对应的key
if (it == NULL)
{
// 分配内存用于存储新的键值对
struct hashTable* tmp=malloc(sizeof(struct hashTable));
// 设置新的键值对的键和值
tmp->key=ikey;
tmp->val=ival;
// 使用HASH_ADD_INT宏将新的键值对插入哈希表
HASH_ADD_INT(hashtable,key,tmp);
}
// 如果找到了对应的key,则更新它的值
else
{
it->val=ival;
}
}
HASH_ADD_INT
是<hash.h>
库中定义的一个宏,用于在哈希表中添加一个新的元素。这个宏通常用于创建和维护一个键值对列表,其中键是一个整数。
主函数,查找两数之和
int* twoSum(int* nums,int numSize,int target,int* returnSize)
{
// 初始化哈希表为NULL
hashtable = NULL;
// 遍历数组nums
for(int i =0;i<numSize;i++)
{
// 在哈希表中查找目标值减去当前数组元素的值,
struct hashTable* it = find(target-nums[i]);
// 如果找到了对应的值
if(it !=NULL)
{
// 分配内存用于存储结果,大小为两个整数
int* ret=malloc(sizeof(int)*2);
// 将找到的值的索引和当前数组元素的索引存储到结果数组中
ret[0]=it->val;
ret[1]=i;
// 设置返回大小为2,表示找到了两个数
*returnSize =2;
// 返回结果数组
return ret;
}
// 如果当前数组元素在哈希表中不存在,则将其插入哈希表
insert(nums[i],i);
}
// 如果没有找到两个数之和等于目标值的组合,设置返回大小为0
*returnSize = 0;
// 返回NULL,表示没有找到
return NULL;
}