leetcode 两数之和(1)

题目描述

给定一个整数数组 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方式:

  1. 起始时hashmap中没有任何有效数据
  2. 按照数组顺序,针对数组中的每一个元素(用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;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值