close

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

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

按題意來說是可以很快想到簡單的解法, 就是裏面兩個數字相加起來會等於目標

那麼就直接從最開始嘗試一直往後加就可以 nums[0] +nums[1] , num[0] + nums[2], ... nums[1] + nums[2], nums[1] + nums[3]....

不過題目中有聲明最後會free 掉記憶體,要用malloc 所以 不用的話就會有以下的error (就是手建想試試看)

------------------------------------------------------------------------------------------------------------

如果使用result[2]就會出現
load of null pointer of type 'const int'
使用不夠的空間做例如 malloc(4)
assign value to arrary時就會產生
store to address 0x000002531290 with insufficient space for an object of type 'int'

--------------------------------------------------------------------------------------------------------------

好不管這些error, 如果用以上的方法submit就會有

int* twoSum(int* nums, int numsSize, int target) {
    int *result =  malloc(sizeof(int) * 2);
    for (int i = 0; i < numsSize-1  ; i++){
        for (int j = i+1; j < numsSize ; j++){
            if (target == nums[i] + nums[j]){
                result[0] = i;
                result[1] = j;
                break;   
            }
        }
    }
    return result;
}

此"正常人"想到的方式能達到141ms, 當然, 很多大大是不能滿足於這個需要使用到 O(n^2) 複雜度的

所以就要用到hash table 的概念, 當中每個hash node 是 value 是原先input值  key 為target - input 

typedef struct HashNode {
    int key;
    int val;
} HashNode;

typedef struct HashMap {
    int size;
    HashNode** storage;
} HashMap;

HashMap* hash_create(int size);
void hash_destroy(HashMap* hashMap);
void hash_set(HashMap* hashMap, int key, int value);
HashNode* hash_get(HashMap* hashMap, int key);

HashMap* hash_create(int size){
    HashMap* hashMap = malloc(sizeof(HashMap));
    hashMap->size = size;
    hashMap->storage = calloc(size, sizeof(HashNode*));
    return hashMap;
}

void hash_destroy(HashMap* hashMap) {
    for(int i=0; i < hashMap->size; i++) {
        HashNode *node;
        if((node = hashMap->storage[i])) {
            free(node);
        }
    }
    free(hashMap->storage);
    free(hashMap);
}

void hash_set(HashMap *hashMap, int key, int value) {
    int hash = abs(key) % hashMap->size;
    int flag = hash;
    HashNode* node;
    while ((node = hashMap->storage[hash])) {
        if (hash < hashMap->size - 1) {
            hash++;
        } else {
            hash = 0;
        }
        if (hash == flag) {
            return;
        }
    }
    node = malloc(sizeof(HashNode));
    node->key = key;
    node->val = value;
    hashMap->storage[hash] = node;
}

HashNode* hash_get(HashMap *hashMap, int key) {
    int hash = abs(key) % hashMap->size;
    int flag = hash;
    HashNode* node;
    while ((node = hashMap->storage[hash])) {
        if (node->key == key) {
            return node;
        }

        if (hash < hashMap->size - 1) {
            hash++;
        } else {
            hash = 0;
        }
        if (hash == flag) {
            break;
        }
    }

    return NULL;
}

int* twoSum(int* nums, int numsSize, int target) {
    HashMap* hashMap;
    HashNode* node;
    int rest, i;
    hashMap = hash_create(numsSize);
    for(i = 0; i < numsSize; i++) {
        rest = target - nums[i];
        node = hash_get(hashMap, rest);
        if (node) {
            int* result = malloc(sizeof(int)*2);
            result[0] = node->val;
            result[1] = i;
            hash_destroy(hashMap);
            return result;
        } else {
            hash_set(hashMap, nums[i], i);
        }
    }
    return NULL;
}

 

arrow
arrow

    紅線 發表在 痞客邦 留言(0) 人氣()