LEETCODE的第一题——两数之和(哈希表)

LEETCODE的第一题——两数之和(哈希表)

本文主要用于记录刷力扣的题解,,因为自己算法太菜,所以想通过深度学习力扣的每一道题目的原理来提高自己。
下面内容为自己学习时的记录,如有错误,欢迎指正🍭

一、 题目——1.两数之和

1

二、 题解一:暴力解法

最先想到的就是使用for循环直接遍历数组,C语言代码如下👇

int *twoSum(int *nums,int numsize,int target, int *returnSize){
    for (int i= 0 ;i<numsize ; i++){
        for(int j =i+1;j<numsize ; j++)
        {if(num[i]+num[j]==target){  //如果找到有两数之和等于目标值,则找到了
            int* ret =malloc(sizeof(int)*2);//创建空间
            ret[0]=i;
            ret[1]=j;
            *returnSize = 2;
            return ret;
        }
    }
    }
    *returnSize = 0;
    return NULL;//没找到返回NULL
}

三、 题解二:哈希表

进阶:你可以想出一个时间复杂度小于 O(n^2) 的算法吗?
看到这个进阶我就知道这个题目不简单,后来看到官方是使用哈希表进行的优化
发现使用纯C是无法快速的使用一些数据结构的算法的(比如这题的哈希表,建立一个哈希表的代码真的很长),所以我后来使用python复现了一下(相比于其他语言,目前就python于我而言更加熟悉)后面有时间的话一定要去学习C++!!!

3.1 哈希表(Hash Table)原理

哈希表是一种常见的数据结构,它用于存储键值对(Key-Value pairs)并提供高效的数据查找、插入和删除操作。其核心原理是散列函数(Hash Function)。

基本原理

  1. 散列函数:哈希表使用散列函数将键(key)映射为一个索引,这个索引用来在内部数组中存储值(value)。这个映射是关键,因为它决定了如何将键分布到数组的不同位置。
  2. 数组存储:哈希表内部通常包含一个固定大小的数组,每一个数组元素被称为“桶”(Bucket)或“槽”(Slot)。这些桶用来存储键值对。散列函数的输出确定了键值对应存储在哪个桶里。
  3. 处理冲突:由于不同的键可能映射到相同的索引,所以冲突是不可避免的。哈希表必须能够有效地处理冲突。常见的处理冲突的方法包括链表法(将多个键对存储在同一个桶中,并使用链表来管理他们)和开放地址法(在冲突时寻找下一个可用的桶)等。
  4. 常见操作:哈希表支持以下常见操作:
    插入(Insertion):将新的键值对插入到哈希表中。首先通过散列函数计算键的索引,然后将值存储在对应的桶中。
    查找(Lookup):根据给定的键查找对应的值。通过散列函数计算索引,然后在相应的桶中查找值。
    删除(Deletion):根据给定的键删除对应的值。通过散列函数计算索引,然后从相应的桶中删除值。
  5. 性能分析:在理想情况下,良好设计的哈希表可以提供常数时间的平均复杂度(O(1))来执行上述操作。但是,如果哈希表的散列函数不均匀或者桶的数量不足,性能可能会下降,导致冲突增多,使得操作的时间复杂度变为O(n)。

3.2 C语言解题

//自定义一个结构体,用来表示哈希表中的每一个元素,成员包括两个整数成员`key`和`val`分别表示键和值。
struct hashTable{
    int key;
    int val;
    UT_hash_handle hh;//特殊的宏,对象的名称是hh
}

struct hashTable* hashtable;//声明一个名为hashtable的指针变量,该指针可以用来指向 struct hashTable 类型的对象

//声明了一个名为 find 的函数,该函数接受一个整数参数 ikey,并返回一个指向 struct hashTable 类型对象的指针
struct hashTable* find(int ikey){
    struct hashTable* tmp;
    HASH_FIND_INT(hashtable,&ikey,tmp);//使用了 "uthash" 库提供的 HASH_FIND_INT 宏来查找哈希表中是否存在具有指定整数键 ikey 的元素
    return tmp;
}
//向哈希表中插入新的元素
void insert(int ikey,int ival){
    struct hashTable* it =find(ikey);//调用 find 函数来检查是否已存在具有相同的键
    if(it==NULL){//不存在
        struct hashTable* tmp = malloc(sizeof(struct hashTable));//创建一个新的 hashTable 结构体
        tmp->key =ikey;
        tmp->val =ival;
        HASH_ADD_INT(hashtable,key,tmp);//HASH_ADD_INT 宏将其添加到哈希表
    }
    else{//如果已存在具有相同'键'的元素,它将更新该元素的值。
        it->val=ival;
    }
}
//具体实现函数
int* twoSum(int*nums,int numSize, int target, int* returnSize){
    hashtable = NULL;
    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;
            *returnSize = 2;
            return ret;
        }
        insert(nums[i],i);

    }
    *returnSize = 0;
    return NULL;
}

利用 “uthash” 库来实现哈希表,通过自定义的结构体和一些宏来操作哈希表中的元素

3.3 python 解题

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashtable = dict()  #创建一个空的字典(哈希表)hashtable,用于存储整数与其索引之间的映射关系
        for i, num in enumerate(nums):  #元素值 num 和索引 i
            if target - num in hashtable:
                return [hashtable[target - num], i]#hashtable[target - num] 表示之前已经存储在哈希表中的整数的索引,i 表示当前遍历的整数的索引
            hashtable[nums[i]] = i  #nums[i] 作为键,索引 i 作为值存储
        return []

使用字典(哈希表)来解决两数之和的问题。它遍历整数列表,查找是否存在两个元素的和等于目标值,并返回这两个元素的索引。如果没有找到匹配,返回一个空列表。这种方法的时间复杂度为O(n),其中n是列表的大小。

可以很直观的看出来python的代码比c语言简练很多/(ㄒoㄒ)/~~


写在最后:
1.不要想着纯C编程,最好同时熟练使用C和C++,如果有机会的话可以在多掌握一门语言,以后机试的时候可能会用到
2.一定要早一点开始练习算法!!还有要坚持!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: LeetCode第一是 Two Sum。目描述是:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。 解法: 1. 暴力枚举法:对于每一个数,遍历整个数组,找到另一个数使得它们的和为 target。时间复杂度为 O(n^2)。 2. Hash 表法:遍历数组,对于每一个数,用 target 减去该数,判断差值是否在数组中出现过,如果出现过就返回该数的下标和差值的下标。时间复杂度为 O(n)。 在 LeetCode 中,你可以使用任意一种方法来解决该。 ### 回答2: leetcode第一是要求找出数组中两个数的和等于给定目标数的索引。可以使用哈希表来解决这个问。 首先,我们可以创建一个空的哈希表。然后,遍历整个数组,对于每一个元素,计算目标数减去当前元素的差值。接着,我们检查差值是否在哈希表中,如果存在,说明当前元素与差值的和等于目标数。我们可以直接返回当前元素和差值在哈希表中的索引。 如果差值不在哈希表中,我们将当前元素及其索引插入哈希表中,以便之后可以通过差值来找到当前元素的索引。遍历完成后,如果没有找到满足条件的索引,返回一个空数组或者其他指定的结果。 使用哈希表的解决方案可以将查找的时间复杂度降低到O(1)。整个算法的时间复杂度为O(n),其中n为数组的长度。算法的空间复杂度为O(n),因为需要额外的哈希表来存储元素及其索引。 总结起来,leetcode第一可以通过使用哈希表来解决,其中遍历数组并将元素及其索引存储在哈希表中,然后查找差值是否在哈希表中,找到满足条件的索引并返回。这个解决方案的时间复杂度为O(n),空间复杂度为O(n)。 ### 回答3: LeetCode是一个在线的编程库,第一是非常简单的算法。这个目要求我们在一个整数数组中找到两个数,使得它们的和等于目标数。解决这个问有几种方法。 一种简单的方法是使用双重循环来遍历数组中的每一对数,然后判断它们的和是否等于目标数。这样的时间复杂度是O(n^2),不是很高效。 另一种更优化的方法是使用哈希表。我们可以遍历一遍数组,将每个数与目标数的差值作为键,对应的索引作为值存放在哈希表中。然后再次遍历数组,每次都判断当前数在哈希表中是否存在,如果存在则说明找到了满足条件的两个数。这种方法的时间复杂度是O(n),空间复杂度也是O(n)。 还有一种更巧妙的方法是使用双指针。我们可以设置两个指针,一个指向数组的起始位置,一个指向数组的末尾位置,然后通过移动指针来逐渐缩小搜索范围。如果指针所指的两个数的和等于目标数,则找到了答案;如果和小于目标数,则将左指针右移一位;如果和大于目标数,则将右指针左移一位。这种方法的时间复杂度也是O(n),但空间复杂度是O(1),比哈希表方法更节省空间。 总之,这个目虽然很简单,但是解决的方法有多种。根据目要求和具体情况,我们可以选择适合的方法来解决这个问
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写的什么石山代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值