leetcode刷题记录(C语言版)——两数之和

1. 两数之和

给定一个整数数组 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]

提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?

2.解题思路  

首先,我们需要了解题目中给定的条件:

  • nums 是一个整数数组,长度为 n,其中 n > 1
  • target 是一个整数,需要在 nums 数组中找出两个数的和等于 target
  • 返回这两个数的下标,下标从 0 开始计数,下标可以是重复的,但数字不能重复。

基于这些条件,我们可以使用哈希表的方法来解决问题。具体来说,我们可以使用一个 hashtable 来存储 nums 数组中的数字和下标,然后从头开始遍历 nums 数组,对于当前数字 nums[i],我们计算 target - nums[i],在 hashtable 中查找是否存在这个数,如果存在,则返回这两个数的下标,如果不存在,插入哈希表中以便下次查找。

  首先创建一个哈希表:

// 定义哈希表的结构体
struct hashTable{
    int key;
    int value;
    UT_hash_handle hh; // UT_hash_handle是<hash.h>中定义的一个结构体
} ;

struct hashTable* hashtable;

UT_hash_handle 是在 <hash.h> 中定义的一个结构体,它用于在哈希表中存储元素的元数据,以便实现哈希表的操作。UT_hash_handle 结构体的定义如下:

struct UT_hash_handle {
    void *prev;
    void *next;
    UT_hash_handle *hh;
};

hashTable结构体中,使用 UT_hash_handle hh; 来声明一个 UT_hash_handle 类型的变量,用于在哈希表中存储节点的元数据。

     在哈希表中查找元素:        

struct hashTable* find(int ikey) {
    struct hashTable* tmp;
    HASH_FIND_INT(hashtable, &ikey, tmp);
    return tmp;
}

HASH_FIND_INT 是 C 标准库中 <hash.h> 头文件定义的一个宏,它用于在哈希表中查找一个键值对。如果找到了键值对,它将返回键的值,否则返回 NULL

        在哈希表中插入元素

// 定义函数insert,它接受一个整数key和一个整数val,表示要插入的键值对
void insert(int ikey, int ival) 
{
   // 在哈希表中查找key
    struct hashTable* it=find(ikey);
  // 如果没有找到对应的key
    if (it == NULL)
    {
    // 分配内存用于存储新的键值对
     struct hashTable* tmp=malloc(sizeof(struct hashTable));
   // 设置新的键值对的键和值
     tmp->key=ikey;
     tmp->val=ival;
   // 使用HASH_ADD_INT宏将新的键值对插入哈希表
     HASH_ADD_INT(hashtable,key,tmp);
    }
    // 如果找到了对应的key,则更新它的值
    else
      {
       it->val=ival;
      }
}

      HASH_ADD_INT 是 <hash.h> 库中定义的一个宏,用于在哈希表中添加一个新的元素。这个宏通常用于创建和维护一个键值对列表,其中键是一个整数。

    主函数,查找两数之和

int* twoSum(int* nums,int numSize,int target,int* returnSize)
{
    // 初始化哈希表为NULL
    hashtable = NULL;

    // 遍历数组nums
    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;
      // 设置返回大小为2,表示找到了两个数
        *returnSize =2;
      // 返回结果数组
        return ret;
    }
    // 如果当前数组元素在哈希表中不存在,则将其插入哈希表
    insert(nums[i],i);

    }
   // 如果没有找到两个数之和等于目标值的组合,设置返回大小为0
    *returnSize = 0;
   // 返回NULL,表示没有找到
    return NULL;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值