题目
- 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
- 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
- 你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
提示:
2 <= nums.length <= 1 0 4 10^4 104
− 1 0 9 -10^9 −109 <= nums[i] <= 1 0 9 10^9 109
− 1 0 9 -10^9 −109 <= target <= 1 0 9 10^9 109
只会存在一个有效答案
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
- 一开始看到查找重复元素,我一下子就想到用两个for循环来找重复的元素。
- 在写完代码之后,我都没想到O( n 2 n^2 n2)的时间复杂度居然可以通过这个题。
- 然后后面在看到提示之后,我看到这个题还可以继续优化。我看到又看到这个题是关于查找的问题,这就让我想起了哈希表。
解法一(暴力解法)
完整代码
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
int* num=NULL;
num=(int*)malloc(2*sizeof(int));//这里要注意返回的数组一定要动态分配内存。
for(int i=0;i<numsSize-1;i++)
{
for(int j=i+1;j<numsSize;j++)
{
if(nums[i]+nums[j]==target)
{
num[0]=i;
num[1]=j;
*returnSize=2;//*returnSize表示的是返回数组的大小,要记得给它赋值。
return num;
}
}
}
return NULL;
}
解法二(哈希表)
哈希函数
int f_hash(int num)
{
return num%10000;
}
哈希表的建立以及初始化
typedef struct map
{
int index;
struct map* next;
}*p;
int maxlen=max(nums,numsSize);
int minlen=min(nums,numsSize);
p hash[10000];
for(int i=0;i<10000;i++)
{
hash[i]=NULL;
}
完整代码
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
typedef struct map
{
int index;
struct map* next;
}*p;
int maxlen=max(nums,numsSize);//寻找最大最小值是因为nums里面的数据里面存在负数,
int minlen=min(nums,numsSize);//但是数组的下表只能大于等于0;需要这两个数来中和负数。
p hash[10000];
for(int i=0;i<10000;i++)
{
hash[i]=NULL;
}
int* numIndex=(int*)malloc(sizeof(int)*2);
for(int i=0;i<numsSize;i++)
{
if(target-nums[i]-minlen<0||hash[f_hash(target-nums[i]-minlen)]==NULL)
{
p t=(p)malloc(sizeof(struct map));//这里在链表中插入新节点的方法是头插法。
t->next=hash[f_hash(nums[i]-minlen)];
hash[f_hash(nums[i]-minlen)]=t;
t->index=i;
}
else
{
p t=(p)malloc(sizeof(struct map));
t=hash[f_hash(target-nums[i]-minlen)];
while(t!=NULL)
{
if(target-nums[i]==nums[t->index])
{
numIndex[0]=t->index;
numIndex[1]=i;
*returnSize=2;
return numIndex;
break;
}
if(t->next==NULL)
{
break;
}
t=t->next;
}
t->next=hash[f_hash(nums[i]-minlen)];
hash[f_hash(nums[i]-minlen)]=t;
t->index=i;
}
}
return NULL;
}
int max(int num[],int n)
{
int maxnum=num[0];
for(int i=1;i<n;i++)
{
if(num[i]>maxnum)
{
maxnum=num[i];
}
}
return maxnum;
}
int min(int num[],int n)
{
int minnum=num[0];
for(int i=1;i<n;i++)
{
if(num[i]<minnum)
{
minnum=num[i];
}
}
return minnum;
}
int f_hash(int num)
{
return num%10000;
}
注释
- 每次写哈希表的时候都只有自己手写哈希函数,uu们就勉强看看吧 😄 。
- 我在看这题的评论时看到一个有趣的评论:“有人相爱,有人夜里开车看海,有人leetcode第一题都做不出来。”
- 如果有啥问题,可以在下面评论区里面提出来哟。