您的位置:首页 > 其它

leetcode第一题<<Tow Sum>>

2016-04-05 00:00 597 查看
摘要: 我不知道我这个算不算抄袭别人的知识成果,其实,我看别人的只是想拓宽一下自己的思路,虽然复制黏贴了。。

最后,想说,距离上篇博客已经一年,这一年其实很快,也发生过很多事,一句话:何必回头伤往事 且把风流唱少年!!

好久没更新博客了,我都不知道天天在忙什么,岁数大了,人就懒了,以前的具体数学博客实在是写不动了,看了几章就扔去垫显示器了,最近突然想起来刷刷leetcode了,不知道为什么。好了,话不多,从0开始刷leetcode,也不知道我能坚持多久,反正慢慢来,经常做题肯定会进步的。。

1. Two Sum

My Submissions

QuestionEditorial Solution

Total Accepted: 212403 Total Submissions: 943126 Difficulty: Easy

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.
Example:

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

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


题目传送门:Two sum

下面说说我的思路吧:这题当时我拿到手就感觉很容易啊,于是不到15分钟就代码ok,提交也过了

这道题目最容易想的方法是暴力法,就是用两个for循环遍历每一种可能的组合,并判断结果是否等于target。这种方法的时间复杂度是O(n^2),代码如下:

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


然后我就提交通过了,因为以前看过很多数据结构或者算法竞赛的书,就感觉这个也太简单了,而而且传说以前这种方法是不给通过的,时间复杂度太高了,就去网上搜了一下别人的方法,有个osc的大兄弟是这样解的:

用hash表:只需遍历一遍数组,如果
nums[i]
没有在hash表中,则将
target-nums[i]
作为键,
i
作为值存储在hash表中。否则找到,返回hash表中键为
nums[i]
的键值对的值,并计算两个索引返回。这种方法时间复杂度是O(n)。他的代码如下(他竟然自己写了一个hash函数):

int * twoSum(int* nums, int numsSize, int target) {    int * indexs;    int i;

indexs = (int *)malloc(2 * sizeof(int));    memset(indexs, 0, sizeof(indexs));

node * ht
;    for(i = 0; i < N; i++)
{
ht[i] = NULL;
}    for(i = 0; i < numsSize; i++)
{
node * p = search_by_key(ht, nums[i]);        if(p)
{            /*如果存在,那么找到,索引为p->data.value+1和i+1 */
indexs[0] = p->data.value + 1;
indexs[1] = i + 1;            return indexs;
}        else
{            /* 如果不存在,就将target-nums[i],i存储在哈希表中*/
insert(ht, target-nums[i], i);
}
}    return indexs;
}
#define N 100#define abs(x) (((x)>0)?(x):(-x))typedef struct DATATYPE{    int key;    int value;
}data_type;typedef struct NODE{
data_type   data;    struct NODE * next;
}node;/**
* 搜索hash表
*/node * search_by_key(node * ht
, int key)
{
node * p;    int addr = abs(key % N);
p = ht[addr];    while(p && p->data.key != key)
p = p->next;    return p;
}/**
* 插入hash表
*/void insert(node * ht
, int key, int value){    int addr;
node * p, * s;

s = (node *)malloc(sizeof(node));
s->data.key = key;
s->data.value = value;

p = search_by_key(ht, key);    if(p)
{/*记录存在*/
free(s);
}    else
{
addr = abs(s->data.key % N);
s->next = ht[addr];
ht[addr] = s;
}
}


他也提示了还有一种方法:先把数组从小到大排序,再用两个指针从数组两头向中间夹。初始时
left = 0
rigth = numsSize-1
,然后如果
nums[left] + nums[right] < target
,则
left++
;如果
nums[left] + nums[right] > target
,则
right--
;否则找到结果并返回。在这一题中这种思路有个问题是要主要保存排序前数字对应的索引。这种方法时间复杂度是O(nlogn)。

我不知道我这个算不算抄袭别人的知识成果,其实,我看别人的只是想拓宽一下自己的思路,虽然复制黏贴了。。

最后,想说,距离上篇博客已经一年,这一年其实很快,也发生过很多事,一句话:何必回头伤往事 且把风流唱少年!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode hash 暴力法