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].
思路:先对数组排序,然后定义两个指针分别指向头尾,看指向的两数之和是否等于目标值,不等则对应向后或向前头尾指针。复杂度O(nlogn+n)=O(nlogn),好于直接枚举O(n^2)。
但是由于返回的是下标值,不能直接排序,将数值和下标组成pair后再排序,这样比较麻烦。class Solution {
public:
static bool cmp(pair<int,int> a, pair<int,int> b)
{
return a.first < b.first;
}
vector<int> twoSum(vector<int>& nums, int target) {
int len = nums.size();
vector<pair<int,int>> a;
vector<int> res;
for(int i = 0; i < len; i++)
a.push_back(make_pair(nums[i], i));
sort(a.begin(),a.end(),cmp);
int i = 0, j = len - 1;
while(i<j)
{
int tmp = a[i].first + a[j].first;
if(tmp == target)
{
res.push_back(a[i].second);
res.push_back(a[j].second);
break;
}
else if(tmp < target)
i++;
else
j--;
}
return res;
}
};
或者采用map,从前向后搜索,记录每个数的下标。对于i,看target-nums[i]是否为map中的key值,如果是说明已找到。
class Solution {
public:
vector<int> twoSum(vector<int> &numbers, int target) {
vector<int> ret(2,-1);
unordered_map<int, int> m; //value->index map
for(int i = 0; i < numbers.size(); i ++)
{
if(m.find(target-numbers[i]) == m.end())
//target-numbers[i] not appeared
m[numbers[i]] = i;
else
{
ret[0] = m[target-numbers[i]];
ret[1] = i;
return ret;
}
}
}
};
3Sum
在2sum基础上加一层for循环。
class Solution {
public:
set<vector<int>> S;
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
for(int k=0;k<nums.size();k++)
{
int i=k+1;int j=nums.size()-1;
int target = 0;
while(i<j)
{
int tmp = nums[i]+nums[j]+nums[k];
if(tmp == target)
{
S.insert({nums[k],nums[i],nums[j]});
while(++i<j&&nums[i]==nums[i-1]);
while(--j>i&&nums[j]==nums[j+1]);
}
else if(tmp < target)
i++;
else
j--;
}
}
return vector<vector<int>>(S.begin(),S.end());
}
};
4Sum
在3Sum基础上再加一层for循环,当然有更好的方法,但是太麻烦了,我懒得去试了。。。
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
set<vector<int>> S;
sort(nums.begin(), nums.end());
for(int i = 0; i < int(nums.size()-3); i++)
for(int j = i + 1; j < int(nums.size()-2); j++)
{
int left = j + 1;
int right = nums.size() - 1;
while(left < right)
{
int tmp = nums[i] + nums[j] + nums[left] + nums[right];
if(tmp == target)
{
S.insert({nums[i], nums[j], nums[left], nums[right]});
while(++left < right && nums[left] == nums[left - 1]);
while(--right > left && nums[right] == nums[right + 1]);
}
else if(tmp < target)
left++;
else
right--;
}
}
return vector<vector<int> > (S.begin(), S.end());
}
};