一、Two Sum
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, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].
解法:一开始是先排序,再设置两个指针分别指向排序后的容器首尾,向内部移动确定两个元素位置。但是这个方法没有考虑返回的是原来元素的位置。实际的返回是排序后位置。
考虑用map容器。map的key和value是一一对应的,而且key是唯一的。用map来存储原来数组的元素与位置。
map的查找复杂度是log(N);
不多说,看代码:
vector<int> twoSum(vector<int>& nums, int target)
{
vector<int>res;
map<int,int>m;
for(int i=0;i<nums.size();i++)
{
m[nums[i]]=i;//若有重复元素,map会保存位置靠后的元素与位置。
}
for(int j=0;j<nums.size();j++)
{
int t=target-nums[j];
map<int,int>::iterator it;
it=m.find(t);//迭代器的作用是判断有没有找到
if(it!=m.end()&&m[t]!=j)
{
res.push_back(j);
res.push_back(m[t]);
break;
}
}
return res;
}
整体复杂度是NlogN。二、3Sum
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note: The solution set must not contain duplicate triplets.
For example, given array S = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
因此可以先排序,三个数中一个做target,转换为Two Sum中一开始我的想法,用两个指针首尾向内靠近。
vector<vector<int>> threeSum(vector<int>& nums)
{
vector<vector<int> >res;
set<vector<int> >s;//set保证解不会重复
if(nums.size()<3)
return res;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size()-2;i++)//这里我们把-nums[i]看做是target
{
int j=i+1;
int k=nums.size()-1;
while(j<k)
{
int sum=nums[i]+nums[j]+nums[k];
if(sum==0)
{
vector<int>temp;
temp.push_back(nums[i]);
temp.push_back(nums[j]);
temp.push_back(nums[k]);
s.insert(temp);
j++;
k--;
}
else if(sum<0)
j++;
else
k--;
}
}
res=vector<vector<int> >(s.begin(),s.end());
return res;
}
三、4Sum
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note: The solution set must not contain duplicate quadruplets.
For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0. A solution set is: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]解法:这题和3Sum基本思路一样,只是再加上一层循环
vector<vector<int> >res;
set<vector<int> >s;
if(nums.size()<4)
return res;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size()-3;i++)
{
for(int p=i+1;p<nums.size()-2;p++)
{
int j=p+1;
int k=nums.size()-1;
while(j<k)
{
int sum=nums[i]+nums[j]+nums[k]+nums[p];
if(sum==target)
{
vector<int>temp;
temp.push_back(nums[i]);
temp.push_back(nums[p]);
temp.push_back(nums[j]);
temp.push_back(nums[k]);
s.insert(temp);
j++;
k--;
}
else if(sum<target)
j++;
else
k--;
}
}
}
res=vector<vector<int> >(s.begin(),s.end());
return res;