题意: 从一个无序数组中找到两个数(一定存在)使其和等于target,返回两个数的下标号,时间尽可能的优。
(1)因为有并且只有一组,我们可以先将数组排序,设置两个指针,一前一后,通过和的不同的情况移动指针,但是因为有了排序的过程,时间复杂度NlogN
struct node
{
int value;
int indexx;
}N[100005];
bool comp(node a,node b)
{
return a.value<b.value;
}
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int tot=nums.size();
vector<int> ans;
for(int i=1;i<=tot;i++)
{
N[i].value=nums[i-1];
N[i].indexx=i;
}
sort(N+1,N+tot+1,comp);//sort
int left=1,right=tot;
while(left<right)
{
if(N[left].value+N[right].value==target)
{
if(N[left].indexx<=N[right].indexx)//注意要先输出编号小的
{
ans.push_back(N[left].indexx);
ans.push_back(N[right].indexx);
return ans;
}
else
{
ans.push_back(N[right].indexx);
ans.push_back(N[left].indexx);
return ans;
}
}
else if(N[left].value+N[right].value<target)
left++;
else if(N[left].value+N[right].value>target)
right--;
}
}
};
(2)O(n)解法。空间换时间,采用hash的方法,hash[数值]=index;由当前的数值判断target-cur是否存在。
注意用map实现,但是不能用数组,因为有可能题目中会出现负数,hash[-8]=9;这样就会出现错误。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> mp;
mp.clear();
vector<int> ans;
int tot=nums.size();
for(int i=0;i<tot;i++)
{
int now=mp[target-nums[i]];
if(now)
{
ans.push_back(now);
ans.push_back(i+1);
return ans;
}
else
mp[nums[i]]=i+1;
}
}
};