码迷,mamicode.com
首页 > 其他好文 > 详细

Two Sum问题

时间:2016-10-05 13:11:08      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:

题目描述:

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 = 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==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问题

标签:

原文地址:http://www.cnblogs.com/evilkant/p/5932004.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!