力扣刷题笔记1——两数之和(涉及查找表法)

上题。。。

基础思想:一开始看到题,很多人都会灵光一现,这不是数学里面组合问题嘛,只需要将数组中的数据两两组合,相加比对,就能找出答案。用代码实现无非是一个嵌套for循环的事。

复杂度考察:先固定第一个数,依次与后面n-1个数组合,再固定第二个数,与后面n-2个数组合...最后一个固定的是倒数第二个数,与最后一个数组合。因此复杂度为(n-1)+(n-2)+...1=n(n-1)/2=

On^2。

升维思想:刚刚是在数组里找两个组合数比对其和与target,何不让target减去其中一个数,在数组中找有没有匹配的另一个数呢?

查找表法

查表法指的是先将一些计算好的数据存在一个长量数组中,需要时直接调用。比如创建一个哈希表,根据key直接查找其value

此题中数组元素的值就是key,索引就是value。从第一个数开始算出another=target-nums[0],查找哈希表中有无another。没有就继续,有就直接返回目前索引值和another对应哈希表中的value。

 复杂度:最多需要做减法n次,查找n次,所以复杂度为On,明显小于基础算法

代码解析

struct hashTable {
    int key;
    int val;
    UT_hash_handle hh;                                                  //hh是内部使用的hash处理句柄,在使用                                                                                             过程中,只需要在结构体中定义一个                                                                                                UT_hash_handle类型的变量即可,不需                                                                                            要为该句柄变量赋值,但必须在该结构体                                                                                          中定义该变量

};                                                                                     //创建哈希表数据类型

struct hashTable* hashtable;                                          //创建哈希表结构指针变量(全局)

struct hashTable* find(int ikey) {                                      //实现查找接口的函数 
    struct hashTable* tmp;                                                  需要先定义一个哈希类型的指针
    HASH_FIND_INT(hashtable, &ikey, tmp);                    用HASH_FIND_INT()函数直接查找,如                                                                                       果有匹配对象将对象复制给刚才定义的指针             
    return tmp;
}

void insert(int ikey, int ival) {
    struct hashTable* it = find(ikey);                 //如果有匹配对象,返回对象的指针,否则返回NULL                                                                                                                                  (it为接口指针)
    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]);
        if (it != NULL) {
            int* ret = malloc(sizeof(int) * 2);
            ret[0] = it->val, ret[1] = i;
            *returnSize = 2;
            return ret;                             //第一个出口,成功
        }
        insert(nums[i], i);
    }
    *returnSize = 0;
    return NULL;                                     //第二个出口,失败
}

代码作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/two-sum/solution/liang-shu-zhi-he-by-leetcode-solution/
来源:力扣(LeetCode)
附上一个自己为了更直观地理清思路画的不规范的流程图

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值