第一种暴力求解法,用两个循环,找到这样的数就直接返回,时间复杂度为O(N^2)
int* twoSum(int* nums, int numsSize, int target)
{
int *sum,i,j;
sum=malloc(sizeof(int)*2);
for(i=0;i<numsSize-1;i++)
for(j=i+1;j<numsSize;j++)
{
if(target==nums[i]+nums[j])
{
sum[0]=i;
sum[1]=j;
return sum;
}
}
return sum;
}
上面那种方法虽然简单,但是耗时,第二种方法采用Hash存储数据和它的下标,这样空间复杂度为O(N),这样以空间换时间,时间复杂度为O(N),运行时间减少到4ms,完美!
typedef struct HashNode
{
int indice;
int value;
struct HashNode *next;
}*List;
typedef struct Hash
{
int size;
List Thelist;
}*Hashtable;
int NextPrime(int N)//求不小于N的最小素数
{
int i;
if(!(N%2))N++;//保证N是奇数
for(;;N=N+2)
{
for(i=(int)sqrt(N);i>2;i--)
if(!(N%i))break;
if(2==i)break;
}
return N;
}
void Insert(Hashtable H,List L)
{
int key;
key=(unsigned int)L->value%H->size;//注意输入值有负数,所以key的值可能为负,但是数组下标不能为负,所以要用unsigned int将其转化为正整数
L->next=H->Thelist[key].next;
H->Thelist[key].next=L;
}
int Search(Hashtable H,int value)
{
int key;
List p;
key=(unsigned int)value%H->size;
p=H->Thelist[key].next;
while(p)
{
if(value==p->value)
return p->indice;
p=p->next;
}
return 0;
}
int* twoSum(int* nums, int numsSize, int target)
{
int *sum,i,x,y;
Hashtable H;
List temp;
sum=malloc(sizeof(int)*2);
H=malloc(sizeof(struct Hash));
H->size=NextPrime(numsSize);
H->Thelist=malloc(sizeof(struct HashNode)*H->size);
for(i=0;i<H->size;i++)
H->Thelist[i].next=NULL;
for(i=0;i<numsSize;i++)
{
temp=malloc(sizeof(struct HashNode));
temp->value=nums[i];
temp->indice=i;
Insert(H,temp);
}
for(i=0;i<numsSize;i++)
{
x=i;
y=Search(H,target-nums[i]);
if(y&&x!=y)
{
sum[0]=x<y?x:y;
sum[1]=x+y-sum[0];
return sum;
}
}
return sum;
}
第三种用c++中的STL中的map,时间复杂度也是O(N),但是程序代码比C语言的简单的多
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
vector<int>result;
if(nums.size()==0)
return result;
unordered_map<int,int>number;
for(int i=0;i<nums.size();i++)
{
if(number.find(target-nums[i])==number.end())
number[nums[i]]=i;
else
{
result.push_back(number[target-nums[i]]);
result.push_back(i);
break;
}
}
return result;
}
};
第四种方法:双指针法
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
vector<int>result;
vector<int>temp(nums);
if(nums.size()==0)
return result;
sort(nums.begin(),nums.end());
int i=0;
int j=nums.size()-1;
int sum;
while(i<j)
{
sum=nums[i]+nums[j];
if(sum==target)
{
for(int k=0;k<temp.size();k++)
{
if(temp[k]==nums[i]||temp[k]==nums[j])
result.push_back(k);
}
return result;
}
else if(sum<target)
i++;
else
j--;
}
return result;
}
};