题目描述
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
可以采用暴力循环的方式来解决该问题,但该方法比较费时间,此处介绍采用hashmap方式:
- 起始时hashmap中没有任何有效数据
- 按照数组顺序,针对数组中的每一个元素(用A表示),在target-A对应的hashmap中寻找对应的元素,若找到,则退出,若没有找到,则元素A存储到hashmap中,因此每个元素其实是在其之前的元素中寻找target-A
这样的好处是之前遍历过的元素存储在hashmap中,而hashmap的查询时间相对较快,从容提升了效率,但因为hashmap占用内存,从而牺牲了空间。
需要考虑的特殊情况:
1.数组中存在负数,在代码实现中的代码中,-A和A存储在相同的hashmap位置处
2.输入数组的元素个数小于2
3.没有找到符合要求的元素
代码注意事项:
post出来的代码还可以使用指针数组来实现,这样更节省资源,感兴趣的可自行实现
代码实现
下述代码摘自Mokusesei,但其内部使用了开源的uthash,但其效率最佳。
typedef struct hash_node {
int id; /* we’ll use this field as the key /
int index;
UT_hash_handle hh; / makes this structure hashable */
} hash_node;
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
int *two_nums = (int *)malloc(sizeof(int)*2);
hash_node *hash_table = NULL, *hash_item1 = NULL, *hash_item2 = NULL;
for (int i = 0; i < numsSize; i++) {
// 查找哈希表中是否存在满足和为target的另一个值,若存在直接返回
int other_id = target - *(nums+i);
HASH_FIND_INT(hash_table, &other_id, hash_item1);
if (hash_item1) {
two_nums[0] = hash_item1->index;
two_nums[1] = i;
*returnSize = 2;
return two_nums;
}
// 将本次遍历的值放入哈希表,value为数组下标,key为对应数值
hash_item2 = (hash_node *)malloc(sizeof(hash_node));
hash_item2->id = *(nums+i);
hash_item2->index = i;
HASH_ADD_INT(hash_table, id, hash_item2);
}
return two_nums;
}
作者:Mokusesei
链接:https://leetcode-cn.com/problems/two-sum/solution/cyu-yan-yi-bian-ha-xi-kong-jian-onhuan-shi-jian-on/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
下述代码是不采用uthash库的方式
typedef struct hash_node {
int id; /* we’ll use this field as the key /
int index;
struct hash_node next;
} hashNode;
hashNode hashtable[20];
/**
-
Note: The returned array must be malloced, assume caller calls free().
/
int twoSum(int* nums, int numsSize, int target, int* returnSize){
if((nums == NULL) && (numsSize <= 1))
{
*returnSize = 0;
return NULL;
}memset(hashtable,-1,sizeof(hashNode) * 20);
int index_tmp = 0;
struct hash_node* tmp = NULL;
struct hash_node* newnode = NULL;
int* ret = malloc(sizeof(int)*2);for(int i = 0; i < numsSize; i++)
{
if(target <= nums[i])
{
index_tmp = nums[i] - target;
}
else
{
index_tmp = target - nums[i];
}
tmp = &(hashtable[(index_tmp)%20]);
while((tmp != NULL) && (tmp->index != -1))
{
if(tmp->id == (target - nums[i]))
{
*returnSize = 2;
ret[0] = tmp->index;
ret[1] = i;
return ret;
}
tmp = tmp->next;
}
if(nums[i] <= 0)
{
index_tmp = (0 - nums[i]) % 20;
}
else
{
index_tmp = nums[i] % 20;
}
if(hashtable[(index_tmp)%20].index == -1)
{
hashtable[index_tmp].index = i; //没有找到目标,则入hash表,以便后续元素查找对应的元素
hashtable[index_tmp].id = nums[i];
hashtable[index_tmp].next = NULL;
continue;
}
tmp = &(hashtable[(index_tmp)%20]);
while(tmp != NULL)
{
if(tmp->next == NULL)
{
newnode = malloc(sizeof(struct hash_node));
newnode->index = i; //没有找到目标,则入hash表,以便后续元素查找对应的元素
newnode->id = nums[i];
newnode->next = NULL;
tmp->next = newnode;
break;
}
tmp = tmp->next;
}
}
*returnSize = 0;
return ret;
}