【刷题】leetcode 1 . 两数之和

这篇具有很好参考价值的文章主要介绍了【刷题】leetcode 1 . 两数之和。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【刷题】leetcode 1 . 两数之和,刷题,leetcode,哈希算法,散列表,c语言,数据结构,算法,学习

两数之和

题目链接

【刷题】leetcode 1 . 两数之和,刷题,leetcode,哈希算法,散列表,c语言,数据结构,算法,学习

1 思路一 (简单突破)

最简单的思想: 遍历 从头开始逐个遍历。
首先选定 加数1 然后寻找 加数2 ,如果两者之和满足条件 target 。返回相应下标即可!

int* twoSum(int* nums, int n, int target, int* returnSize) {

    for(int i = 0;i < n;i++){
    //加数1 从头开始
        for(int j = i + 1;j < n;j++){
        //加数2 从加数1 后一位开始
            if(nums[i]+nums[j] == target){
            //满足条件即可返回对应下标
                int* a = (int*)malloc(2*sizeof(int)) ;
                a[0] = i;
                a[1] = j;
                //返回的数组大小
                *returnSize = 2;
                //返回数组
                return a;
            }
        }
    }
    //如果全不满足 返回NULL
    *returnSize = 0;
    return NULL;
}

提交! 过啦!!!
【刷题】leetcode 1 . 两数之和,刷题,leetcode,哈希算法,散列表,c语言,数据结构,算法,学习

但是看看运算时间,居然这么慢!确实咱们的算法时间复杂度是O(n^2),不够快速。
才打败了 69% 的用户。我们不能满足当下,让我们思考有没有其他思路。

2 思路二 (进行优化)

  1. 仔细想想,上面的遍历属实比较费时间,那我们如何改进它呢?
  2. 我的想法是从选择数上下手,取消逐个遍历,改用 二分查找
  3. 二分查找的效率比逐个遍历快许多。但是进行二分查找 的前提是 数组有序!
  4. 如果我们进行简单的排序,那数组下标就被打乱了,无法返回正确值。
  5. 所以我们有必要创建一个新数组,而且是二维数组,储存值和对应下标
  6. 然后不断将和与target 比较,进行二分查找,即可。
//qsort 的比较函数 注意我们传的数据类型是 int* 
static int  compare(int* n1 , int* n2){
    return n1[0] - n2[0] ;
 }
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    int n = numsSize;
    int arr[n][2]; // 分别储存下标和值大小 保证同时移动
    // 将原数组的值以及它对应的下标存入临时数组中
    for (int i = 0; i < n; i++) { 
        arr[i][0] = nums[i]; // 值
        arr[i][1] = i; // 该值对应的下标
    }

    //排序
    qsort(arr,n,sizeof(arr[0]),compare);

    //二分寻找
    for(int i = 0; i < n;i++){
        int left = 0 ,right = n-1;//区间[0 , n-1]
        while(left <= right){
            int mid = (left + right) / 2;//区间中点
            //检查是否和为target 并且 两数下标不能相同(否则就是同一个数)
            if(arr[mid][0] + nums[i] == target && i != arr[mid][1] )
            {
                *returnSize = 2 ; //两个数
                
                //开辟两个int类型的空间
                int* ret = (int*)malloc(sizeof(int)*2); 
                //记录两个数下标
                ret[0] = i;
                ret[1] = arr[mid][1];
                return ret;
            }
            //如果大于target 则在小区间寻找
            else if(arr[mid][0] + nums[i] > target){
                right = mid-1;
            }
            //如果小于target 则在大区间寻找
            else {
                left = mid + 1;
            }
        }
    }
    //没有找到
    *returnSize = 0;
    return NULL;

}

提交! 过啦!!!!!!!
【刷题】leetcode 1 . 两数之和,刷题,leetcode,哈希算法,散列表,c语言,数据结构,算法,学习
这下子打败了98%的用户。我们从 120 ms 一下子来到 8 ms。
时间复杂度来到O(nlogn).
简直就是飞机和马车的差距
那么问题来到为什么还有 2% 比我们快????????
我看了大佬们的代码,使用到了哈希表 而我现在还不会!哭了。
o(╥﹏╥)oo(╥﹏╥)o!o(╥﹏╥)oo(╥﹏╥)o!o(╥﹏╥)oo(╥﹏╥)o!

3 思路三 (哈希表 我还不会)

下面给大家看一下大佬的 0 ms 的代码。

#define HashSize 107 // 哈希表大小

typedef struct Node { // 哈希结点
    int value; // 值
    int index; // 下标
    struct Node* next; // 下指针
}Node;

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    int n = numsSize; // 数组长度
    Node* hash[HashSize]; // 哈希表
    for (int i = 0; i < HashSize; i++) { // 初始化哈希表
        hash[i] = (Node*)malloc(sizeof(Node));
        hash[i]->value = hash[i]->index = -1;
        hash[i]->next = NULL;
    }
    for (int i = 0; i < n; i++) { // 遍历一遍原数组
        int pos = abs(target - nums[i]) % HashSize; // 找到target - nums[i]在哈希表中对应的位置
        Node* head = hash[pos];
        while (head->next && head->next->value != target - nums[i]) head = head->next; // 找该位置是否有target - nums[i]这个值
        if (head->next) { // 找到符合题意的值
            *returnSize = 2;
            int* ans = (int*)malloc(sizeof(int) * 2);
            ans[0] = i; ans[1] = head->next->index; // 写入答案
            for (int i = 0; i < HashSize; i++) free(hash[i]);
            return ans;
        }
        pos = abs(nums[i]) % HashSize; // 找到nums[i]在哈希表中对应的位置
        head = hash[pos];
        while (head->next) head = head->next; // 写在这个位置的末尾
        head->next = (Node*)malloc(sizeof(Node));
        head->next->value = nums[i]; // 写入该值
        head->next->index = i; // 写入该值对应的下标
        head->next->next = NULL;
    }
    for (int i = 0; i < HashSize; i++) free(hash[i]);
    *returnSize = 0;
    return NULL;
}

作者:星开祈灵
链接:https://leetcode.cn/problems/two-sum/solutions/2326455/1-liang-shu-zhi-he-by-xing-kai-qi-ling-vxt6/
来源:力扣(LeetCode)
著作权归作者所有。

C语言的缺陷 , 需要手撕哈希表。
来看大佬 C++ 的代码,真的非常美观!!!!
美!!!! 帅!!!! 炸裂!!!!文章来源地址https://www.toymoban.com/news/detail-794714.html

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int,int> a;//提供一对一的hash
        vector<int> b(2,-1);//用来承载结果,初始化一个大小为2,值为-1的容器b
        for(int i=0;i<nums.size();i++)
        {
            if(a.count(target-nums[i])>0)
            {
                b[0]=a[target-nums[i]];
                b[1]=i;
                break;
            }
            a[nums[i]]=i;//反过来放入map中,用来获取结果下标
        }
        return b;
    };
};

作者:陈乐乐
链接:https://leetcode.cn/problems/two-sum/solutions/4361/liang-shu-zhi-he-by-gpe3dbjds1/
来源:力扣(LeetCode)
著作权归作者所有。

谢谢阅读Thanks♪(・ω・)ノ

下一篇文章见!!!

到了这里,关于【刷题】leetcode 1 . 两数之和的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • LeetCode:1两数之和 C语言

    1. 两数之和 给定一个整数数组  nums  和一个整数目标值  target ,请你在该数组中找出  和为目标值  target   的那  两个  整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案

    2024年04月13日
    浏览(36)
  • 算法刷题-哈希表-三数之和

    用哈希表解决了两数之和,那么三数之和呢? 力扣题目链接 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。 注意: 答案中不可以包含重复的三元组。 示例: 给定数组 nums = [-1, 0, 1, 2

    2024年02月09日
    浏览(47)
  • 算法刷题-哈希表-四数之和

    一样的道理,能解决四数之和 那么五数之和、六数之和、N数之和呢? 力扣题目链接 题意:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。 注意:

    2024年02月09日
    浏览(82)
  • 代码随想录第6天| 哈希表理论基础 ,LeetCode242.有效的字母异位词,LeetCode349. 两个数组的交集,LeetCode202. 快乐数,LeetCode1. 两数之和

    哈希表(散列表)理论基础 : 哈希表是根据关键码的值而直接进行访问的数据结构。 直白来讲其实数组就是一张哈希表。   什么时候想到用哈希法, 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法 。 当我们遇到了要快速判断一个元素是否出现集

    2024年02月10日
    浏览(66)
  • 算法训练第5天|哈希表理论基础 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和

    哈希表是根据 关键码 的值而直接进行访问的数据结构。 一般哈希表都是用来快速判断一个元素是否出现集合里。 数组、集合set、映射map 力扣链接 题目描述: 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 注意: 若  s  和  t   中每个字符出现的

    2024年02月19日
    浏览(45)
  • 哈希-力扣01两数之和

    给定一个整数数组  nums  和一个整数目标值  target ,请你在该数组中找出  和为目标值  target   的那  两个  整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。 示例 1:

    2024年01月20日
    浏览(41)
  • 代码随想录 -- 哈希表--两数之和

    力扣hot1:两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。 示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] +

    2024年02月09日
    浏览(38)
  • 解决两数之和问题的哈希表方法

    在给定整数数组中寻找和为目标值的两个整数,并返回它们的数组下标。通过暴力枚举或哈希表方法,时间复杂度小于O(n^2)。Java和C++代码解决方案。

    2024年02月01日
    浏览(48)
  • 数据结构算法设计——哈希表(散列表)

            哈希表 又叫 散列表 ,他们两个是同一个东西,本文全文采用“散列表”的叫法。散列表的本质其实就是一个 数组 ,他的作用就像使用数组时一样,输入下标可以得到对应元素,散列表可以实现 输入一个的时候得到这个的地址信息 。 下面是百科给出

    2024年02月03日
    浏览(60)
  • leetcode - 01两数之和

    时间复杂度读 O ( n 2 ) O(n^2) O ( n 2 ) 空间复杂度 O ( 1 ) O(1) O ( 1 )

    2024年02月12日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包