LeetCode每日一题 008 两数之和

1、解题思路


思路一:

双层循环,遍历查找每一个元素 与其匹配的 另一值是否在数组中。优点是直观易表示,确定是时间复杂度为o(n*n);

思路二:

空间换时间,使用哈希表保存所有元素与其位置的关系,则在已知其中一个元素A与target的条件下,另一个元素B=targe-A,再通过hash表查找,可在o(1)时间得到B元素位置。

2、有效题解


/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
typedef struct hashNode
{
    int node_key;
    int node_value;
} hashNode_t;

typedef struct hashMap
{
    hashNode_t **node_array;
    int map_size;
} hashMap_t;

hashMap_t *hashMap_create(int size)
{
    hashMap_t *map = (hashMap_t *)malloc(sizeof(hashMap_t));
    map->node_array = (hashNode_t **)malloc(sizeof(hashNode_t *) * size);
    int i;
    for (i = 0; i < size; i++)
    {
        map->node_array[i] = NULL;
    }
    //memset(map->node_array, 0, size);
    map->map_size = size;

    return map;
}

int hash_fn(int key, int map_size)
{
    return abs(key) % map_size;
}

hashNode_t *hashMap_get(int key, hashMap_t *map)
{
    int index = hash_fn(key, map->map_size);
    hashNode_t *node = map->node_array[index];
    while (NULL != node && key != node->node_key)
    {
        if (index == map->map_size - 1)
        {
            index = 0;
        }
        else
        {
            index++;
        }
        node = map->node_array[index];
    }

    return node;
}

void hashMap_put(int key, int value, hashMap_t *map)
{
    int index = hash_fn(key, map->map_size);
    hashNode_t *node;
    while ((node = map->node_array[index]))
    {
        if (index == map->map_size - 1)
        {
            index = 0;
        }
        else
        {
            index++;
        }
    }
    node = (hashNode_t *)malloc(sizeof(hashNode_t));
    node->node_key = key;
    node->node_value = value;
    map->node_array[index] = node;
}

int* twoSum(int* nums, int numsSize, int target) {
    
    if (NULL == nums || numsSize <= 1)
    {
        return NULL;
    }

    int *ret = (int *)malloc(sizeof(int) * 2);
    assert(NULL != ret);

    hashMap_t *map = hashMap_create(numsSize);

    int i;
    int other_num;
    hashNode_t *node;
    int has_find = 0;

    for (i = 0; i < numsSize; i++)
    {
        other_num = target - nums[i];
        if ((node = hashMap_get(other_num, map)) != NULL)
        {
            ret[0] = i < node->node_value ? i : node->node_value;
            ret[1] = i > node->node_value ? i : node->node_value;
            has_find = 1;
            break;
        }
        else
        {
            hashMap_put(nums[i], i, map);
        }
    }

    if (!has_find)
    {
        free(ret);
        ret = NULL;
    }

    return ret;
}

3、复杂度分析


哈希查找法,遍历数组简历哈希表,时间复杂度o(n),增加额外哈希表,空间复杂度o(n)。

4、小结


1、查找时使用哈希表可在o(1)时间复杂度完成,常用来空间换取时间。

2、哈希表几个关键要素:

1)记录<key, value>结构的hash_node, 保存hash_node的数组table

2)哈希方法hash_fn,常见的直接寻址、平方取中等 (本例注意abs(key))

3)哈希冲突解决办法,常见的冲突链、开放寻址、再散列法。

3、指针数组的用法

4、哈希表的内存释放(本例未完整考虑,有内存泄露)

5、memset是逐字节填充的,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值