Leetcode question brushing record: 1 sum of two numbers (array hash)

Posted by Bullit on Wed, 09 Feb 2022 06:03:33 +0100

Leetcode question brushing record: 1 sum of two numbers (array hash)

Title stem:

Given an integer array nums and an integer target value target, please find the two integers with and as the target value target in the array and return their array subscripts.
You can assume that each input will correspond to only one answer. However, the same element in the array cannot appear repeatedly in the answer.

  1. Brute force solution: nest two for loops and enumerate them one by one until the sum is found as target, and return the subscript of these two numbers.
/**
 1. Adopt dynamic array method;
 2. Note: The returned array must be malloced, assume caller calls free().
 */
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    int i;
    int j;
    int *ret;
    for(i=0;i<numsSize;i++){
        for(j=i+1;j<numsSize;j++){
            if(nums[i]+nums[j]==target){
                ret=(int*)malloc(sizeof(int)*2);
                ret[0]=i;
                ret[1]=j;
                *returnSize=2;
                return ret;
            }
        }
    }
    *returnSize=0;
    return 0;
}

Note: the time complexity of this method is O(n^2) and the space complexity is O(1).

  1. Hash table method: improve the brute force solution. The second for loop is to find target nums [i] with time complexity O(n), and use hash table time complexity O(1) to find target nums [i].

The overall idea is:
Traverse the array and calculate the difference between the element num [i] of the first for loop and the target value target, that is, othernum = target num [i].
Then look up othernum in the hash table. If it exists, it means that two numbers are found, and the sum is equal to target. If it does not exist, the value of the currently inspected element is taken as the key and its corresponding index i is taken as the value and stored in the hash table.

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
struct Hashmap{
    int key;
    int value;
    UT_hash_handle hh;
};

struct Hashmap* hashtable;

struct Hashmap* find(int ikey){
    struct Hashmap* temp;
    HASH_FIND_INT(hashtable,&ikey,temp);
    return temp;
}

void insert(int ikey,int ivalue){
    struct Hashmap* temo;
    temo=find(ikey);
    if(temo==NULL){
        struct Hashmap* addhash=malloc(sizeof(struct Hashmap));
        addhash->key=ikey;
        addhash->value=ivalue;
        HASH_ADD_INT(hashtable,key,addhash);
    }
    else{
        temo->value=ivalue;
    }
}


int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    hashtable=NULL;
    int i;
    int j;
    int anothernumber;
    int *ret;
    for(i=0;i<numsSize;i++){
        anothernumber = target-nums[i];
        struct Hashmap* hashelement=find(anothernumber);
        if(hashelement!=NULL){
            ret=malloc(sizeof(int)*2);
            ret[0]=hashelement->value;
            ret[1]=i;
            *returnSize=2;
            return ret;
        }
        insert(nums[i],i);
    }
    *returnSize=0;
    return NULL;
}

Note: the time complexity is O(n), and the space complexity is O(n).
The comparison of the two running times is shown in the following figure:
The comparison between execution time and memory consumption before and after the figure above is obvious.

Supplement:

Hashifa code uses utHash code. uthash
Is the open source code of C, which implements common hash operation functions, such as build, find, insert, delete and so on. This set of open source code adopts macro to realize the relevant functions of hash function, and supports any data structure of C language. The key value is the most, and even multiple values can be used as the key. Whether it is user-defined struct or basic data type, it should be noted that the operation interface mode of different types of keys is slightly different.
When using uthash code, you only need to include the header file "uthash.h". Since the code is implemented in macro mode, all the implementation codes are in uthash H file, so you only need to include the header file in your own code.

The English usage document of uthash is as follows:
http://troydhanson.github.io/uthash/userguide.html#_add_item

Error record:

  • Error record 1:

In the second screenshot above, the running error is due to the initialization of hashtable in the twoSum function
The original function is:

int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    int i;
    int j;
    int anothernumber;
    int *ret;
    for(i=0;i<numsSize;i++){
        anothernumber = target-nums[i];
        struct Hashmap* hashelement=find(anothernumber);
        if(hashelement!=NULL){
            ret=malloc(sizeof(int)*2);
            ret[0]=hashelement->value;
            ret[1]=i;
            *returnSize=2;
            return ret;
        }
        insert(nums[i],i);
    }
    *returnSize=0;
    return NULL;
}

Join initialization

hashtable=NULL;

After that, it runs correctly.
Input is:
[3,3]
6
My output:
[0,0]
Correct output:
[0,1]

It is speculated that the reason is the impact of the previous test. The details are not clear. Please add when you understand

  • Error record 2:
    HASH_ADD_INT(hashtable,key,addhash);
    The first parameter of this function is the hash table, the second parameter is the name of the key field, and the third parameter is the pointer structure to be added. If this place is written as
    HASH_ADD_INT(hashtable,ikey,addhash); NULL will be output.
    HASH_ ADD_ Pay attention to int() function!!!

Topics: Algorithm data structure leetcode