算法(C)(两数之和)

2023-10-26

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

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

解法一:猫猫直接上暴力枚举法

思路:使用两层for循环,枚举每一个数组中的元素使得将 nums[i] + nums[j] == target 成立的数组下标保存到新开辟的数组ans中,若不成立则返回空数组即可。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    for(int i = 0; i < numsSize; i++)
    {
        for(int j = i+1; j < numsSize; j++)
        {
            if(nums[i] + nums[j] == target)
            {
                *returnSize = 2;
                int *ans = (int *)malloc(sizeof(int) * 2); //创建指针数组ans
                ans[0] = i;
                ans[1] = j;
                return ans;
            }
        }
    }
    *returnSize = 0;
    return NULL;
}

解法二:哈希表(想了半小时属实是菜呜呜)

思路:遍历一遍原数组nums,在遍历过程中,将访问过的数 nums[i] 元素以及它的下标 i 存入哈希表中。 原问题 nums[i] + nums[j] == target 转化为:判断 target - nums[i] =>(nums[j])这个值是否在哈希表中。即每遍历到一个 i,就去判断 target - nums[i] =>(nums[j])这个值是否在哈希表中。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */

 #define HashSize 100       //宏定义哈希表大小

 typedef struct Node        //创建哈希结点
 {
     int key;       //关键值
     int index;     //下标
     struct Node *next; //指向下一个的指针结点
 }Node;

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

    Node *H[HashSize];  

    //初始化哈希表
    for(int i = 0; i < HashSize; i++)
    {
        H[i] = (Node *)malloc(sizeof(Node));
        H[i]->key = H[i]->index = -1;
        H[i]->next = NULL;
    }

    //遍历一遍原来的数组
    for(int i = 0; i < numsSize; i++)
    {
        int p = abs(target - nums[i]) % HashSize;   //找到  target - nums[i] 在哈希表对应的的位置
        Node *head = H[p];  //临时结点head
        while(head->next && head->next->key != target - nums[i] )  
        {
            head = head->next;
        }
        if(head->next != NULL)  //能找该位置target - nums[i]这个值的情况(找到符合题意的值)
        {
            *returnSize = 2;
            int *ans = (int *)malloc(sizeof(int) * 2);   //创建临时数组的内存空间
            ans[0] = i;
            ans[1] = head->next->index;
            for(int j = 0; j < HashSize; j++)
            {
                free(H[j]);
            }
            return ans;
        }

        p = abs(nums[i]) % HashSize;   //找到 nums[i] 在哈希表对应的的位置
        head = H[p];
        while(head->next)      //目的是将 nums[i]的值写到哈希表末尾
        {
            head = head->next;
        }
        head->next = (Node *)malloc(sizeof(Node));  //将最后的空指针位置next域创建新的结点
        head->next->key = nums[i];    //写入 nums[i] 的值
        head->next->index = i;        //写入 nums[i] 的下标
        head->next->next = NULL;
    }

    for(int j = 0; j < HashSize; j++)
    {
        free(H[j]);
    }

    *returnSize = 0;
    return NULL;
}

解法三:排序+二分(猫猫没有想到这种方法,在大神提醒下觉得挺合理的)

思路:可以先对原数组nums进行排序,排序过程中,维护每个值所对应的下标 i 遍历一遍原数组,枚举(i, j)中的 i ,每遍历到一个 i,就通过二分法来寻找符合题意的 j。此方法用到排序还是得用临时数组先存储原数中对应的元素及下标,然后二分法枚举排序后的数组元素,符合条件的数组元素到临时数组取出下标即可。这种方法效率最高,最优解!

static int cmp(const void* a, const void* b) { //qsort()的外部自定义比较函数
    return ((int*)a)[0] - ((int*)b)[0]; //按值从小到大排序
}

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    int arr[numsSize][2]; //初始化临时二维数组
    for (int i = 0; i < numsSize; i++) { //将原数组的值以及它对应的下标存入临时二维数组中
        arr[i][0] = nums[i]; //值
        arr[i][1] = i; //该值对应的下标
    }
    qsort(arr, numsSize, sizeof(arr[0]), cmp); //按值排序
    for (int i = 0; i < numsSize; i++) { //遍历一遍原数组
        int left = 0, right = numsSize - 1; //二分区间:[0, numsSize - 1]
        while (left <= right) { //闭区间二分模板
            int mid = (left + right) / 2;
            if (arr[mid][0] == target - nums[i] && i != arr[mid][1]) { //找到符合题意的值
                *returnSize = 2;
                int* ans = (int*)malloc(sizeof(int) * 2);
                ans[0] = i; ans[1] = arr[mid][1]; 
                return ans;
            }
            else if (arr[mid][0] > target - nums[i]) right = mid - 1;
            else left = mid + 1;
        }
    }
    *returnSize = 0;
    return NULL;
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

算法(C)(两数之和) 的相关文章

随机推荐

  • 数据库中动态列的几种设计思路

    在需求开发的时候 可能会碰到一种场景 在需求中 涉及的某具体业务中 属性是动态的 在条件允许的情况下 可以使用穷举法对所有可能情况进行属性分析 然后进行分类 最终可以形成一套可以解决的方案 这通常是理想情况 Leader和客户通常不会给这个
  • 浅述python中argsort()函数的用法

    由于想使用python用训练好的caffemodel来对很多图片进行批处理分类 学习过程中 碰到了argsort函数 因此去查了相关文献 也自己在python环境下进行了测试 大概了解了其相关的用处 为了怕自己后面又忘了 就写下来权当加深理
  • 合肥工业大学计算机组成原理课设-系统硬件综合设计

    作者简介 CSDN内容合伙人 信息安全专业在校大学生 系列专栏 信息安全本科生课设 系统硬件综合设计报告 新人博主 欢迎点赞收藏关注 会回访 舞台再大 你不上台 永远是个观众 平台再好 你不参与 永远是局外人 能力再大 你不行动 只能看别人
  • nvm 下载/删除/升级以及基本命令

    1 nvm 下载 安装路径不能有中文 下载地址 NVM下载 NVM中文网 卸载之前所有Node后安装nvm 直接运行nvm setup exe文件 选择安装nvm的安装路径 选择nodejs路径 5 打开cmd 输入nvm 检查是否安装成功
  • QT QWidgetAttribute

    目录 QT QWidgetAttribute 说明 参考链接 QT QWidgetAttribute 说明 Constant Value Description Qt WA AcceptDrops 78 Allows data from d
  • C语言中的可移植类型:stdint.h和inttypes.h

    stdint h和inttypes h两个头文件是C99里新增加的 以确保C语言的类型在各系统中功能相同 在stdint h头文件中 C语言为现有类型创建了更多类型名 如 int32 t表示32位有符号整数类型 即 在32位int型系统中
  • navicat配置远程链接mysql数据库(回顾)

    mysql 数据库在同一网关环境下 用navicat配置远程链接 省去命令操作
  • 不死神兔--java解决斐波那契数列

    不死神兔也叫做斐波那契数列或者叫做黄金分割数列或者叫做兔子数列 不死神兔问题 有1对兔子 从出生后的第3个月起每个月都生一对兔子 小兔子长到第三个月后每个月又生一对兔子 假如兔子都不死 问第n个月有几对兔子 需求 我们这里需要知道第二十个月
  • 【深度学习】全连接层 (Full Connection,FC)

    Introduce 全连接层也是一种卷积层 它的参数基本和卷积层的参数一样 只是它的卷积核大小和原数据大小一致 起到将学到的 分布式特征表示 映射到样本标记空间的作用 用 global average pooling 取代 FC 已经成为了
  • Java开发环境系列:你真的会用eclipse吗?

    第一步 下载Eclipse 并安装 下载链接 http www eclipse org downloads 1 点击 Download Packages 进入Eclipse下载界面 2 找到Eclipse IDE for Java EE D
  • 首创模拟电子计算机,指导日本原子弹投射,这个大佬有点牛

    作者 年素清 责编 王晓曼 出品 程序人生 ID coder life 万尼瓦尔 布什 Vannevar Bush 是美国历史上最伟大的科学家和工程师之一 他在二战时创立美国科学研究局 提出了著名的 曼哈顿计划 并指导了第一颗原子弹试验和日
  • Chapter Four : Python 序列之列表、元组操作详解合集

    目录 一 列表 1 列表基本操作 定义列表 删除列表 访问列表 遍历列表 2 列表常用方法及操作详解 2 1 添加元素 append extend insert 运算符 运算符 2 2 删除元素 del pop remove clear 2
  • flutter系列集合之App项目集成flutter混合开发详细指南大神必学

    消息队列目前流行的有KafKa RabbitMQ ActiveMQ等 它们的诞生无非不是为了解决消息的分布式消费 完成项目 服务之间的解耦动作 消息队列提供者与消费者之间完全采用异步通信方式 极力的提高了系统的响应能力 从而提高系统的网络请
  • 数据挖掘的种种-节课准备

    数据挖掘 Data Mining DM 又称数据库中的知识发现 Knowledge Discover in Database KDD 数据挖掘概述 数据挖掘 Data Mining DM 又称数据库中的知识发现 Knowledge Disc
  • C# InvokeRequired和Invoke

    一 简介 WinForm 关于InvokeRequired与Invoke Jlins的博客 CSDN博客 invokerequired c 是禁止夸线程直接访问控件 InvokeRequired是为了解决这个问题而产生的 当一个控件的Inv
  • cpu与gpu实现矩阵相乘对比

    1 完成矩阵相乘的并行程序的实现 要求 实现2个矩阵 1024 1024 的相乘 数据类型设置为float 1 使用CPU计算 include
  • 开源的一些基础介绍

    国内 淘宝 百度 南航 网易等 国外 新浪 搜狐 facebook ebay google等 成功后的企业也在不断为开源添加新能量 如 taobao和google等 因为他们不但被开源的魅力深深吸引住同时也愿意通过开源提升自我 现在更多的企
  • Wrappers.<实体>lambdaQuery的使用

    文章目录 MP 配置 Service CURD接口 Mapper CURD接口 insert delete update select 条件构造器 LambdaUpdateWrapper Wrappers lt 实体 gt lambdaUp
  • 机器人教育是一种科学的探究方式

    创新是推动经济社会发展的核心驱动力 当前 我国已经深刻认识到世界新科技革命带来的机遇和挑战 以高度的历史责任感 强烈的忧患意识和宽广的世界眼光 把创新作为推动经济社会发展的驱动力量 机器人技术的进步将会对科学与技术的发展产生重要影响 只有开
  • 算法(C)(两数之和)

    题目 两数之和 题目描述 给定一个整数数组 nums 和一个整数目标值 target 请你在该数组中找出 和为目标值 target 的那 两个 整数 并返回它们的数组下标 你可以假设每种输入只会对应一个答案 但是 数组中同一个元素在答案里不