您的位置:首页 > 其它

LeetCode题解——4SUm

2015-07-14 20:02 363 查看
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:

Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
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,固定2个数,另两个数为lo,hi遍历,使用技巧剪枝 pruning,可使得运算速度大大加快,O(n^3),实际远小于O(n^3)

class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> ans;
if(nums.size()<4)  return ans;

sort(nums.begin(),nums.end());

int lo,hi;
int MaxSize = nums.size();//可能组成4Sum的最大数字;
for(int i=0; i<MaxSize-3; i++)
{
if(nums[i]+nums[MaxSize-1]+nums[MaxSize-2]+nums[MaxSize-3]<target) continue;//pruning is so magic
if(nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target) break;//pruning is so magic
if(nums[i]+nums[i+1]+nums[i+2]+nums[MaxSize-1]>target) MaxSize--;//更新MaxSize,注意边界情况的剪枝
for(int j=i+1; j<MaxSize-2;j++)
{
if(nums[i]+nums[j]+nums[MaxSize-1]+nums[MaxSize-2]<target) continue;
if(nums[i]+nums[j]+nums[j+1]+nums[j+2]>target) break;

lo = j+1;
hi = MaxSize-1;
int want = target-nums[i]-nums[j];
while(lo<hi)
{
if(nums[lo]+nums[hi]==want)
{
vector<int> tm;
tm.push_back(nums[i]);
tm.push_back(nums[j]);
tm.push_back(nums[lo]);
tm.push_back(nums[hi]);
ans.push_back(tm);
while(lo<hi&&nums[lo]==nums[lo+1]) lo++;
while(lo<hi&&nums[hi]==nums[hi-1]) hi--;
lo++;
hi--;
}
else if(nums[lo]+nums[hi]>want) hi--;
else lo++;
}
while(nums[j]==nums[j+1]) j++;
}
while(nums[i]==nums[i+1]) i++;
}
return ans;
}
};

/*class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>>  result;
if(nums.size() < 4) return result;

vector<int> solution(4,0);
std::sort(nums.begin(),nums.end());
int sum,a,b,c,d,Max_d_when_a_increase = nums.size() - 1,Max_d_when_b_increase;

//a,b,c,d are the four index
//Max_d_when_a_increase is the max possible d when a increase. To have the same sum, when a increase, d can only decrease
//Max_d_when_b_increase is the max possible d when b increase

for( a = 0; a < Max_d_when_a_increase - 2;a++ )
{
//remove dupilcate & pruning if a too small or too big
if((a>0 && nums[a] == nums[a-1])
|| nums[a] + nums[Max_d_when_a_increase] + nums[Max_d_when_a_increase-1] + nums[Max_d_when_a_increase-2] < target) continue;
if(nums[a]+nums[a+1]+nums[a+2]+nums[a+3] > target) break;

//update Max_d_when_a_increase
sum = nums[a]+nums[a+1]+nums[a+2];
while(sum+nums[Max_d_when_a_increase] > target)Max_d_when_a_increase--;
Max_d_when_b_increase = Max_d_when_a_increase;

solution[0] = nums[a];
for( b=a+1; b < Max_d_when_b_increase - 1;b++)
{
//remove dupilcate & pruning if b too small or too big
if((b>a+1 && nums[b] == nums[b-1])
|| nums[a] + nums[b] + nums[Max_d_when_b_increase-1] + nums[Max_d_when_b_increase] < target) continue;
sum = nums[a] + nums[b]+nums[b+1];
if(sum + nums[b+2] > target) break;

//update Max_d_when_b_increase
while(sum+nums[Max_d_when_b_increase]>target) Max_d_when_b_increase--;

solution[1] = nums[b];
c = b+1;
d = Max_d_when_b_increase;
sum = nums[a] + nums[b];
while(c < d)//this are the same as two sum
if(sum + nums[c] + nums[d] == target)
{
solution[2]=nums[c];
solution[3]=nums[d];
result.push_back(solution);

do{c++;}while(c < d && nums[c] == nums[c-1]);
do{d--;}while(c < d && nums[d] == nums[d+1]);
}
else if(sum + nums[c] + nums[d] < target)
do{c++;}while(c < d && nums[c] == nums[c-1]);
else do{d--;}while(c < d && nums[d] == nums[d+1]);
}
}
return result;
}
};*/


[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: