您的位置:首页 > 其它

leecode_18 4Sum (k Sum)

2016-06-01 16:10 281 查看
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)


本题固然可以用一堆if-else来解决,但是为了找到k个数的和的通用解法,固不采用if-else嵌套的方法。

初步设想是先排序,然后用BFS来解决,但是考虑到有重复的数字,单纯BFS会导致输出的集合中有重复,所以要对BFS做些变换(c++描述):

首先队列的元素类型为pair<vector<int>,int>, vector<int>为当前的序列,而int则为最后一个元素的index;

如此,只要遇到重复的元素,所有的int都为重复的元素的最后一个元素的index,如{0,0,0},则生成三个pair压入队列中,即

( {0}, 2 ) ( { 0,0 }, 2) ( {0,0,0}, 2 )

如此,就不会出现 ( {0},0 ) ( {0}, 1 ) ( {0,0} ,1) ( {0,0}, 2) ( {0,0},2), 从而避免输出中重复项的计算

附上c++代码实现,还有优化的空间 :)

#include <iostream>
#include <string>
#include <unordered_map>
#include <queue>
#include <unordered_set>
using namespace std;

vector<vector<int>> fourSum(vector<int>& nums, int target) {
int k=4;
vector<vector<int>> res;
queue< pair< vector<int>,int > > que;
sort(nums.begin(),nums.end());
//ini
for (int i=0;i<nums.size();i++){
int low_bound=lower_bound(nums.begin(), nums.end(),nums[i])-nums.begin();
int up_bound=upper_bound(nums.begin(),nums.end(),nums[i])-nums.begin();
vector<int> temp;
for (int i=low_bound;i<up_bound;i++){
temp.push_back(nums[i]);
que.push(make_pair(temp,up_bound-1));
}
i=up_bound-1;
}

while(!que.empty()){
vector<int> vec=que.front().first;
int index=que.front().second;
que.pop();
//cout<<endl;
int sum=0;
for (int i=0;i<vec.size();i++)
sum+=vec[i];
if (vec.size()==k && sum==target){
res.push_back(vec);
continue;
}

if (vec.size()==k-1 && index<=nums.size()-2)
for (int i=index+1;i<nums.size();i++){
if (sum+nums[i]==target){
vec.push_back(nums[i]);
res.push_back(vec);
break;
}
continue;
}

if (vec.size()<k-1 && index<=nums.size()-2){
int temp=sum;
vector<int> v_temp=vec;
for (int i=index+1;i<nums.size();i++){
int p=nums[i];
int low_bound=lower_bound(nums.begin(), nums.end(),p)-nums.begin();
int up_bound=upper_bound(nums.begin(),nums.end(),p)-nums.begin();

for (int i=low_bound;i<up_bound;i++){
sum+=nums[i];
vec.push_back(nums[i]);
if (vec.size()<=k){
//                        for (int j=0;j<vec.size();j++)
//                            cout<<vec[j]<<" ";
//                        cout<<endl;
que.push(make_pair(vec,up_bound-1));
}

}
vec=v_temp;
sum=temp;
i=up_bound-1;
}
}

}

return res;
}

int main(){
vector<int> vec1={1,0, -1, 0, -2, 2};

vector<vector<int>> res=fourSum(vec1,0);

for (int i=0;i<res.size();i++){
for(int j=0;j<res[i].size();j++)
cout<<res[i][j]<<" ";
cout<<endl;
}

return 0;

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