您的位置:首页 > 其它

【LeetCode】18. 4Sum (2 solutions)

2014-12-21 11:11 417 查看
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:

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)


先确定前两个数num[i],num[j],

然后设置双指针k,l分别指向两端,往中间扫。

(1)(sum = num[i]+num[j]+num[k]+num[l]) == taget,则找到其中一个解。k++,l--.

(2)sum > target, l--

(3)sum < target, k++

解法一:

用map去重

注:不可以使用unordered_map,不然会报错:

error C2440: “类型转换”: 无法从“const std::vector<_Ty>”转换为“size_t”


根据unordered_map的源码来看:

// TEMPLATE CLASS hash
template<class _Kty>
class hash
: public unary_function<_Kty, size_t>
{    // hash functor
public:
size_t operator()(const _Kty& _Keyval) const
{    // hash _Keyval to size_t value by pseudorandomizing transform
ldiv_t _Qrem = _CSTD ldiv((long)(size_t)_Keyval, 127773);

_Qrem.rem = 16807 * _Qrem.rem - 2836 * _Qrem.quot;
if (_Qrem.rem < 0)
_Qrem.rem += 2147483647;
return ((size_t)_Qrem.rem);
}
};


key必须转换为size_t类型,对应于hash表下标。

保险起见,非内置类型就不要作为unordered_map的key了。

class Solution {
public:
vector<vector<int> > fourSum(vector<int> &num, int target) {
vector<vector<int> > result;
if(num.empty() || num.size() < 4)
return result;
int size = num.size();
sort(num.begin(), num.end());
map<vector<int>, bool> m;
for(int i = 0; i < size-3; i ++)
{
for(int j = i+1; j < size-2; j ++)
{
int k = j+1;    //k < size-1
int l = size-1;
while(k < l)
{
int sum = num[i]+num[j]+num[k]+num[l];
if(sum == target)
{
vector<int> cur(4,0);
cur[0] = num[i];
cur[1] = num[j];
cur[2] = num[k];
cur[3] = num[l];
if(m.find(cur) == m.end())
{
result.push_back(cur);
m[cur] = true;
}
k ++;
l --;
}
else if(sum > target)
l --;
else
k ++;
}
}
}
return result;
}
};




解法二:

不用开辟新的空间,通过跳过已访问过的元素来去重。

class Solution {
public:
vector<vector<int> > fourSum(vector<int> &num, int target) {
vector<vector<int> > ret;
int size = num.size();
sort(num.begin(), num.end());
for(int i = 0; i < size; i ++)
{
//skip same i
while(i > 0 && i < size && num[i] == num[i-1])
i ++;
for(int j = i+1; j < size; j ++)
{
//skip same j
//attention: the first element (num[i+1]) should not be skipped
while(j > i+1 && j < size && num[j] == num[j-1])
j ++;

int k = j + 1;
int l = size - 1;
while(k < l)
{
int sum = num[i] + num[j] + num[k] + num[l];
if(sum == target)
{
vector<int> cur(4);
cur[0] = num[i];
cur[1] = num[j];
cur[2] = num[k];
cur[3] = num[l];
ret.push_back(cur);
k ++;
l --;
//skip same k
while(k < l && num[k] == num[k-1])
k ++;
//skip same l
while(l > k && num[l] == num[l+1])
l --;
}
else if(sum < target)
{
k ++;
//skip same k
while(k < l && num[k] == num[k-1])
k ++;
}
else
{
l --;
//skip same l
while(l > k && num[l] == num[l+1])
l --;
}
}
}
}
return ret;
}
};


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