首页 > 代码库 > Two Sum问题

Two Sum问题

题目描述:

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.

样例:

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

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

 

这是我刷leetcode的第一题,读懂题目后,果断采用暴力枚举的办法。

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

令人吃惊的是这个算法的运行时间竟然打败了80%的提交算法,我自己都惊了。我猜那80%的人是遍历所有可能之后才返回indices。总之,不管如何,暴力(brute force)肯定不会是这题的最优解法。

暴力法的时间复杂度很明显是O(n^2),那么更快的算法是什么呢。

如果我们采用桶排序的思想建立一个integer范围大小的数组bucket,扫描一遍输入数组,将bucket数组初始化,再扫描一遍输入数组,对每个输入元素检查bucket[target-nums[i]]的值,如果是1则往后扫描使得nums[j]==target-nums[i],然后return[i,j]。这个算法是一个O(n)的算法。但是一个建立integer范围大小的数组空间消耗也太大了,粗略算了一下需要16G的内存空间,直接GG。

但是大体思路是正确的,如果我们能快速地确定target-nums[i]是否存在,就能省去许多无谓的扫描。但是通过一个integer范围大小的数组来创建一个直接映射表是不可行的,那么思路就比较明确了,哈希表呗。

typedef struct node{    int indice;    int value;    struct node *next;}node;node map[197];int hashFunc(int key){    if(key<0)        key=-key;    return key%97;}void insert(int i, int num) {    node *tmp,*p;    int val;    val = hashFunc(num);    tmp =(node *) malloc(sizeof(node));    tmp->indice = i;    tmp->value =http://www.mamicode.com/ num;    tmp->next = NULL;    for (p = &map[val]; p->next != NULL; p = p->next)        ;    p->next = tmp;}int search(int num){    int val=hashFunc(num);    node *p;    for(p=map[val].next;p!=NULL;p=p->next)        if(p->value=http://www.mamicode.com/=num)            return p->indice;    return -1;}int* twoSum(int* nums, int numsSize, int target) {    int i, j;    for(i=0;i<197;i++)        map[i].next=NULL;    int *indices=(int *)malloc(2*sizeof(int));    for (i = 0; i<numsSize; i++){        insert(i,nums[i]);        j=search(target-nums[i]);        if(j!=-1&&j!=i){            indices[0]=j;            indices[1]=i;            return indices;        }    }    return 0;}

暴力法的时间是209ms,用哈希表的话这个时间就降到了9ms,适当加大map数组的大小,可以达到6ms左右。大概能击败92%的C提交。接下来似乎也没有什么好提速的地方了,比我快的应该是轮子比我造得圆造得好,我还是要多学习一个。

Two Sum问题