小废物的LeetCode100题刷题日记 Day1

文章介绍了如何使用C++中的哈希表数据结构解决两数之和问题,通过遍历数组,查找目标值与数组元素差值对应的元素,找到后返回其索引。展示了find和insert函数在哈希表操作中的应用。
摘要由CSDN通过智能技术生成

/*

题目:两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出

和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9

输出:[0,1]

解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] */

struct hashTable {
    int key;
    int val;
    UT_hash_handle hh;
};

struct hashTable* hashtable;

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

void insert(int ikey, int ival) {
    struct hashTable* it = find(ikey);
    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;
}

// 定义了一个结构体 hashTable,

// 包含了键值对和哈希表的句柄hh。这个结构体用于存储哈希表中的元素。

struct hashTable {
    int key;
    int val;
    UT_hash_handle hh;
};

UT_hash_handle hh; 是一个用于在哈希表中处理链表的字段。

在使用哈希表时,通常会使用链表来解决哈希冲突的问题。UT_hash_handle 是一个特殊的字段,用于将哈希表中的元素链接在一起,形成链表结构。它在每个哈希表元素的结构体中定义。通过将 UT_hash_handle 字段添加到结构体中,可以将该结构体的实例链接到哈希表中。在代码中,UT_hash_handle hh; 表示在 hashTable 结构体中添加了一个名为 hh 的 UT_hash_handle 字段。这样,当将 hashTable 结构体的实例插入到哈希表中时,hh 字段会被用来链接到其他元素,形成链表结构。

// 定义了一个全局变量 hashtable,用于存储哈希表的头指针

struct hashTable* hashtable;

// 定义了两个函数 find 和 insert,用于在哈希表中查找和插入元素。

// find 函数通过调用 HASH_FIND_INT 宏来在哈希表中查找指定的键值对应的元素,并返回找到的元素指针。

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

这个函数的作用是在哈希表 hashtable 中查找指定的键值 ikey 对应的元素,并返回找到的元素指针。在代码中,HASH_FIND_INT 是一个宏,用于在哈希表中查找指定键值的元素。它的参数包括哈希表的名称、要查找的键值以及一个指向存储结果的指针。在这里HASH_FIND_INT(hashtable, &ikey, tmp)表示在 hashtable 哈希表中查找键值为 ikey 的元素,并将结果存储在 tmp 指针中。最后,函数返回 tmp 指针,即查找到的元素指针。如果没有找到对应的元素,则返回空指针 。也就是说调用 HASH_FIND_INT(hashtable, &ikey, tmp); 时,宏会在 hashtable 哈希表中查找键值为 ikey 的元素。如果找到了对应的元素,它会将该元素的指针存储在 tmp 中,以便后续使用。如果没有找到对应的元素,tmp 将被设置为 NULL,表示未找到。

void insert(int ikey, int ival) {
    // 查找哈希表中是否存在指定的键
    struct hashTable* it = find(ikey);
    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;
    }
}

这段代码的逻辑如下:

  1. 首先,通过调用 find 函数查找哈希表中是否存在指定的键 ikey
  2. 如果 find 函数返回的结果为 NULL,表示哈希表中不存在该键,则创建一个新的哈希表节点 tmp,并将键值对赋值给该节点的 key 和 val 字段。
  3. 最后,通过调用 HASH_ADD_INT 宏将新的节点 tmp 插入到哈希表 hashtable 中。
  4. 如果 find 函数返回的结果不为 NULL,表示哈希表中已经存在该键,则直接更新对应节点的值为 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; // 设置返回数组的大小为2
            return ret;
        }
        // 如果不存在,则将当前数插入到哈希表中
        insert(nums[i], i);
    }
    *returnSize = 0; // 如果没有找到符合条件的两个数,则返回空数组
    return NULL;
}

 这段代码的逻辑如下:

  1. 首先,初始化一个哈希表为空。
  2. 然后,使用循环遍历给定的整数数组 nums
  3. 在每次循环中,通过调用 find 函数查找哈希表中是否存在与当前数的差值相等的键。
  4. 如果存在,则说明找到了两个数的索引,创建一个包含这两个索引的数组 ret,并将对应的索引赋值给 ret 数组的元素。
  5. 设置返回数组的大小为2,并返回 ret 数组。
  6. 如果不存在,则将当前数插入到哈希表中,以便后续的查找。
  7. 如果循环结束后仍未找到符合条件的两个数,则设置返回数组的大小为0,并返回空数组。
  • 22
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值