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).
class Solution {
struct Info
{
vector<pair<int, int>>pre;//pair<int,int>里的first代表sinnums里的index,second代表个数
int remainsize;//剩余的数字个数
int remainvalue;//剩余的值
};
bool choose_one(int&k, vector<Info>&candi, map<int, int>&count, vector<int>sinnums)
{
vector<Info>newcandi;
if (k == 1)
{
k--;
for (int i = 0; i < candi.size(); i++)//考虑0
if (candi[i].remainvalue%candi[i].remainsize == 0)
{
int nxtnum = candi[i].remainvalue / candi[i].remainsize;
if (nxtnum>sinnums[candi[i].pre.back().first] && count.find(nxtnum) != count.end()
&& count[nxtnum] >= candi[i].remainsize)
return true;
}
}
else
{
for (int i = 0; i < candi.size(); i++)
{
for (int j = 1; j <= (candi[i].remainsize - k + 1); j++)
{
for (int h = candi[i].pre.back().first + 1; (h < sinnums.size() - k + 1); h++)
{
//粗略做判断,减小候选集大小
if (candi[i].remainvalue <= sinnums[h] * j + sinnums.back()* (candi[i].remainsize - j)
&& candi[i].remainvalue >= sinnums[h] * j + sinnums[h + 1] * (candi[i].remainsize - j)
&& j <= count[sinnums[h]])
{
Info info;
info.pre = candi[i].pre;
info.pre.push_back(pair<int, int>(h, j));
info.remainsize = candi[i].remainsize - j;
info.remainvalue = candi[i].remainvalue - j*sinnums[h];
newcandi.push_back(info);
}
}
}
}
k--;
candi = newcandi;
}
return false;
}
bool threeSum(vector<int>& nums, int target)
{
if (nums.empty())
return false;
map<int, int>count;
for (int i = 0; i < nums.size(); i++)
count[nums[i]]++;
map<int, int>::iterator it = count.end(); it--;
if (target >= 0 && count.begin()->first> target
|| target < 0 && it->first < target)
return false;
vector<int>sinnums;
for (it = count.begin(); it != count.end(); it++)
sinnums.push_back(it->first);
int neednum = 3;
//答案里只有一种数字
if (target%neednum == 0 && count.find(target / neednum) != count.end() && count[target / neednum] >= neednum)
return true;
for (int i = 0; i < sinnums.size(); i++)
{
//答案里有k种数字,2<=k<=neednum
for (int k = 2; k <= neednum; k++)
{
if (sinnums.size() - i >= k)
{
int jjmax = neednum - k + 1 < count[sinnums[i]] ? neednum - k + 1 : count[sinnums[i]];
for (int j = 1; j <= jjmax; j++)
{
Info inf;
inf.pre.push_back(pair<int, int>(i, j));
inf.remainsize = neednum - j;
inf.remainvalue = target - j*sinnums[i];
vector<Info>candi;
candi.push_back(inf);
int kk = k - 1;
bool f = false;
while (kk > 0 && !f)
f = choose_one(kk, candi, count, sinnums);
if (f)
return true;
}
}
}
}
return false;
}
public:
int threeSumClosest(vector<int>& nums, int target)
{
int pp = 0;
bool f = threeSum(nums, target);
if (f)
return target;
while (true)
{
f = threeSum(nums, target + pp);
if (f)
return target + pp;
f = threeSum(nums, target - pp);
if (f)
return target - pp;
pp++;
}
};
};
acceped
还是借上题的代码。。。
你可以说我是刷博客吧