您的位置:首页 > 其它

Leetcode -- 4Sum

2015-08-25 12:00 246 查看
题目:

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)

分析:

数组,找到四个数,使得其和等于target。

思路:

排序,遍历。将4Sum处理成3Sum,再根据3Sum的求解方法即可。

代码:

class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int> > result;
vector<vector<int> > arr;
int sum, len = nums.size();
if(len < 4)  return result;
sort(nums.begin(), nums.end());
for(int i =0; i< len - 3; i++)
{
if( i == 0 || nums[i - 1] != nums[i])
{
sum = target - nums[i];
arr = threeSum(nums, sum, i+1);
if(arr.size() != 0)
{
for(int j =0; j< arr.size(); j++)
{
result.push_back({nums[i], arr[j][0], arr[j][1], arr[j][2]});
}
}
}
}
return result;
}

vector<vector<int>> threeSum(vector<int>& nums, int tt, int start) {
vector <vector<int> > result;
int len = nums.size();
int front, back, sum, target;

for(int i = start; i< len; i++)
{
front = i + 1;
back = len -1;
target = tt -nums[i];
while(front < back)
{
sum = nums[front] + nums[back];
if(sum < target) front ++;
if(sum > target) back --;
if(sum == target)
{
vector<int> arr(3, 0);
arr[0] = nums[i];
arr[1] = nums[front];
arr[2] = nums[back];
result.push_back(arr);

while(nums[front] == arr[1] && front<back) front ++;
while(nums[back] == arr[2] && front < back) back --;
}
}
while((i+1)<len && nums[i+1] == nums[i])
{
i = i+ 1;
}
}
return result;
}
};


参考Discussion

思路:

hashtable。

The idea is to sort nums first, then build a hashtable with the key as the sum of the pair and the value as a vector storing all pairs of index of num that having the same sum. In this way, all elements stored in hashtable has a order that duplicate pairs are neighbors. Therefore scanning the vector in the hashtable we only put non duplicate elements into the final answer .

代码:

class Solution{ //using hashtable, avg O(n^2)

public:

vector<vector<int> > fourSum(vector<int> &nums, int target){
vector<vector<int> > vvi;
int n = nums.size();
if(n < 4) return  vvi;

sort(nums.begin(), nums.end());
unordered_map<int, vector<pair<int, int>> > mp;
for(int i = 0; i < n; i++){
for(int j = i + 1; j < n; j++){
mp[nums[i]+nums[j]].push_back(make_pair(i,j));
}
}

for(int i = 0; i < n; i++){
if(i>0 && nums[i] == nums[i-1]) continue;
for(int j = i + 1; j < n; j++){
if(j > i + 1 && nums[j] == nums[j-1]) continue;
int res = target - nums[i] - nums[j];
if(mp.count(res)){
for(auto it = mp[res].begin(); it != mp[res].end(); it++){
int k = (*it).first, l = (*it).second;
if(k > j){ // k>j make sure that the second pair has bigger values than the first pair.
if(!vvi.empty() && nums[i]==vvi.back()[0] && nums[j]==vvi.back()[1]
&& nums[k]==vvi.back()[2] && nums[l] == vvi.back()[3]){
continue; //if the obtained 4 elements are the same as previous one continue to next
}
vector<int> vi={nums[i], nums[j], nums[k], nums[l]};
vvi.push_back(vi);
}

}
}
}
}
return vvi;
}
};


PS: 3Sum也是可以用hashtable求解的哦。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息