题目链接:https://leetcode.com/problems/3sum-closest/
题目描述:
Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {-1 2 1 -4}, and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
Subscribe to see which companies asked this question
思路:参考链接:http://blog.csdn.net/doc_sgl/article/details/12462151
参考2sum问题的解法,降低算法复杂度的关键是先排好序,然后设置首尾设置两个指针,当sum>target时,尾部指针--,反之首部指针++,进行线性搜索。 本题不是sum==target,那么只需不断更新最小值。
一开始写的暴力搜索的三个,都超时了,不过功能上应该没有什么问题,测试简单的情况通过了,应该只是时间复杂度比较高。。。
方法一:
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
vector<int> sum;
int result;
int len1=nums.size();
for(int i=0;i<len1;i++)
{
for(int j=i+1;j<len1;j++)
{
for(int k=j+1;k<len1;k++)
{
sum.push_back(nums[i]+nums[j]+nums[k]);
}
}
}
int len2=sum.size();
int index=0;
int minSum=abs(sum[0]-target);
for(int m=0;m<len2-1;m++)
{
if(abs(sum[m+1]-target)<minSum)
{
minSum=abs(sum[m+1]-target);
index=m+1;
}
}
result=sum[index];
return result;
}
};
方法二:
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
vector<int> sum;
int result;
int len1=nums.size();
sum.push_back(nums[0]+nums[1]+nums[2]);
int minSum=abs(sum[0]-target);
int index=0;
int flag=0;
int m=0;
for(int i=0;i<len1;i++)
{
for(int j=i+1;j<len1;j++)
{
for(int k=j+1;k<len1;k++)
{
flag=0;
if(i+j+k==1)
{
flag=1;
break;
}
sum.push_back(nums[i]+nums[j]+nums[k]);
m++;
if(abs(sum[m]-target)<minSum)
{
minSum=abs(sum[m]-target);
index=m;
}
}
if(flag==1)
break;
}
if(flag==1)
break;
}
result=sum[index];
return result;
}
};
方法三:
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
vector<int> sum;
int result;
int len1 = nums.size();
int m = 0;
int tmp;
map<int, int> dif2sumindex;
map <int, int>::iterator beg;
int index;
for (int i = 0; i<len1; i++)
{
for (int j = i + 1; j<len1; j++)
{
for (int k = j + 1; k<len1; k++)
{
tmp = nums[i] + nums[j] + nums[k];
sum.push_back(tmp);
dif2sumindex[abs(tmp - target)] = m;
m++;
}
}
}
beg = dif2sumindex.begin();
index=beg->second;
result = sum[index];
return result;
}
};
方法四:(AC的算法)
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int len=nums.size();
int i=1,j=len-1;
int minDist=abs(nums[0]+nums[1]+nums[len-1]-target);
int result=nums[0]+nums[1]+nums[len-1];
int tmp=0;
for(int k=0;k<len-2;k++)
{
if(k>0&&nums[k]==nums[k-1])
continue;
i=k+1;j=len-1;
while(i<j)
{
tmp=nums[k]+nums[i]+nums[j];
if(abs(tmp-target)<minDist)
{
minDist=abs(tmp-target);
result=tmp;
}
if(tmp==target)
return target;
else if(tmp-target>0)
j--;
else
i++;
}
}
return result;
}
};
题目链接:
https://leetcode.com/problems/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问题的思路,先用两重for循环确定前两个数字,在剩下的数里面用双指针用线性搜索,算法时间复杂度:O(n3),还有待于改进(可能会用到哈希表,还不太熟悉,以后来改进)
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> re;
sort(nums.begin(),nums.end());
map<vector<int>,int> mark;
int n = nums.size();
for (int i = 0; i<n - 3; i++)
{
for (int j = i + 1; j< n - 2; j++)
{
int p1 = j + 1, p2 = n - 1;
int sums = nums[i] + nums[j];
while (p1<p2)
{
if (sums + nums[p1] + nums[p2] == target)
{
vector<int> tmp = { nums[i], nums[j], nums[p1], nums[p2] };
if(mark[tmp]==0)
{
re.push_back(tmp);
mark[tmp]=1;
}
p1++;
p2--;
}
else if (sums + nums[p1] + nums[p2]<target)
p1++;
else
p2--;
}
}
}
return re;
}
};