Two Sum(C语言实现)
哈希(hash)表,亦称散列表,是通过函数映射的方式将关键字和存储位置建立联系,进而实现快速查找。
【问题描述】给定一个整数数组 nums 和一个目标值 target,请给出该数组中和为目标值的两个元素的下标。
每组数组只需求出一种答案。
示例:
给定 nums = [7, 11, 2, 15], target = 9
因为 nums[0] + nums[2] = 7 + 2 = 9
所以返回 [0, 2]
【算法实现】最简单的方法莫过于暴力求解,设计双重循环,直到找到问题的解,而双重循环对应的时间复杂度为O(n^2)。有没有可能降低其复杂度呢?
暴力求解的问题在于盲目遍历,如果我们提前将数组排好序,那么就可以有方向性的进行对比试探,直到找到问题的解。这种查找方式只需要一次循环就能实现,但常见的排序方式的复杂度也都较高。
有没有复杂度为O(n)的算法呢?
我们知道,通过映射方式建立的哈希表可以将查找的复杂度从O(n)降至O(1)。对于哈希表而言,最关键的两个问题是:如何设计散列函数,使得发生冲突的概率尽可能小;同时,如何处理好不可避免的冲突。
对于该问题,假设最小元素为min,那么,对于大于target-min的元素是不需要考虑的。若记max =target-min,我们可以建立一个长度为max-min+1的一维数组hash,就足以存放所有可能的元素。
【算法实现】
将数组中在[min, max]区间的元素从小到大存放在在hash表中,即hash[nums[i]-min]=num[i],表中空余部分填充-1作标记,表示无对应的nums元素。如下表所示:
那么,我们只需要一次循环,看下对应的hash[target-2×min-i]处是否有对应的nums元素即可,即判断hash[target-2×min-i]是否等于-1。如若不等于-1,则查找完毕,返回nums中对应的i+min和target-min+i的小标即可。
代码如下:
int* twoSum(int* nums, int numsSize, int target)
{
int min = 2147483647;
int i;
for (i = 0; i < numsSize; i++)
{
if (nums[i] < min)
min = nums[i];
}
int max = target - min;
int len = max - min + 1; //确定hash长度
int