LeetCode Q1 二和单遍哈希表不工作

Posted

技术标签:

【中文标题】LeetCode Q1 二和单遍哈希表不工作【英文标题】:LeetCode Q1 Two Sum Single Pass Hash Table Not Working 【发布时间】:2022-01-01 14:23:40 【问题描述】:

我正在尝试循环 nums 列表并在哈希表中找到减法,如果没有找到,则将数字插入到哈希表中,直到找到解决方案。但是下面的代码不起作用,有没有人知道我做错了什么?

注意:返回的数组必须是 malloced,假设调用者调用 free()。

int* twoSum(int* nums, int numsSize, int target, int* returnSize)
    
    // create hash table
    // node
    typedef struct node
        int num;
        int index;
        struct node *next;
     node;
    // array
    const unsigned int N = numsSize * 2;
    node *table[N];

    // result
    int *out = malloc(2 * sizeof(int));
     
    // hash function
    unsigned int hash(int num)
        return num * 31337 % N;
    

    // looping the input nums
    for (int i = 0; i < numsSize; i++)

        // calculate compliment
        int compliment = target - nums[i];

        // search for the compliment in linked list
        int compliment_bucket = hash(compliment);
        for (node *n = table[compliment_bucket]; n != NULL; n = n -> next)
            if (compliment == n -> num)
                out[0] = i;
                out[1] = n -> index;
                return out;
            
        

        // if compliment is not in hash table, insert it to the head
        // get the hash value of nums[i]
        int bucket = hash(nums[i]);
        node *tmp = calloc(1, sizeof(node));
        tmp -> num = nums[i];
        tmp -> index = i;
        tmp -> next = NULL;
        if (table[bucket] == NULL)
            table[bucket] = tmp;
        
        else
            tmp -> next = table[bucket];
            table[bucket] = tmp;
        
    

【问题讨论】:

它不起作用是什么意思?顺便说一句,你的代码真的很奇怪,结构和函数是在函数内部定义的。 @kiner_shah 我对 C 编码还很陌生,您介意演示一下如何用 C 编写我的想法吗? 先把所有的结构体和函数定义放到twoSum函数之外。然后看看你得到了什么错误,用这些错误更新这里的帖子(通过复制粘贴以文本格式)。此外,twoSum 似乎返回int* 是的,你可以。你所拥有的甚至不是有效的 C。我不确定typedef,但你绝对不能在 C 中拥有函数而不是其他函数 返回一个由两个整数组成的数组@kiner_shah 【参考方案1】:

我将结构和函数移到了外面。另外,请检查// CHANGE HERE标记的cmets。

#include <stdio.h>
#include <stdlib.h>

// node
typedef struct node
    int num;
    int index;
    struct node *next;
 node;

// hash function
// CHANGE HERE: pass modulo value to function as argument
unsigned int hash(int num, const unsigned int N)
    // CHANGE HERE: to avoid overflows, multiply with the long value `31337` and then compute modulo
    return (num * 31337l) % N;


// CHANGE HERE: added a function to free the memory (for table)
void freeMemory(node** t, const unsigned int N)

    for (int i = 0; i < N; i++)
    
        node* p = t[i];
        while (p)
        
            node* q = p;
            p = p->next;
            q->next = NULL;
            free(q);
        
    
    free(t);


int* twoSum(int* nums, int numsSize, int target, int* returnSize)
    
    // create hash table
    
    // array
    const unsigned int N = numsSize * 2;
    // CHANGE HERE: use calloc for dynamically allocated arrays
    node **table = calloc(N, sizeof(node*));

    // result
    int *out = calloc(2, sizeof(int));
     
    // looping the input nums
    for (int i = 0; i < numsSize; i++)

        // calculate compliment
        int compliment = target - nums[i];

        // search for the compliment in linked list
        int compliment_bucket = hash(compliment, N);
        for (node *n = table[compliment_bucket]; n != NULL; n = n -> next)
            if (compliment == n -> num)
                out[0] = i;
                out[1] = n -> index;
                // CHANGE HERE: free memory before return
                freeMemory(table, N);
                return out;
            
        

        // if compliment is not in hash table, insert it to the head
        // get the hash value of nums[i]
        int bucket = hash(nums[i], N);
        node *tmp = calloc(1, sizeof(node));
        tmp -> num = nums[i];
        tmp -> index = i;
        tmp -> next = NULL;
        if (table[bucket] == NULL)
            table[bucket] = tmp;
        
        else
            tmp -> next = table[bucket];
            table[bucket] = tmp;
        
    
    // CHANGE HERE: free memory before return
    freeMemory(table, N);
    return out;


int main()

    int size = 2;
    int arr[] = 2, 7, 11, 15;
    int* out = twoSum(arr, 4, 9, &size);
    printf("%d %d\n", out[0], out[1]);

【讨论】:

以上是关于LeetCode Q1 二和单遍哈希表不工作的主要内容,如果未能解决你的问题,请参考以下文章

力扣 每日一题 811. 子域名访问计数难度:中等,rating: 1377(字符串切分+哈希表计数)

B树与哈希表

leetcode 数据结构 探索哈希表

数据结构--哈希表

Leetcode刷题100天—706. 设计哈希映射(哈希表)—day74

Leetcode刷题100天—706. 设计哈希映射(哈希表)—day74