LeetCode: 18. 4Sum
题目:
LeetCode:18. 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.
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]
]
分析:
思路:
这个问题是15. 3Sum以及16. 3Sum Closest
此处采用的思路并非是前面的夹逼法,明显不太适用。而是通过unordered_multimap来实现。
1、经过排序后,先计算vector集合中任意两个数字之和存入unordered_multimap中。
2、遍历哈希表,通过equal_range函数来寻找满足nTarget目标的组合,并进行去除重复集合处理。
代码:
vector<vector<int>> fourSum(vector<int>& vecNum, int nTarget) {
vector<vector<int> > vecRes;
if (vecNum.size() < 4)
{
return vecRes;
}
sort(vecNum.begin(), vecNum.end());
unordered_multimap<int, pair<int, int>> mapTemp;
for (size_t i = 0; i < vecNum.size() - 1; ++i)
{
for (size_t j = i + 1; j < vecNum.size(); ++j)
{
mapTemp.insert(make_pair(vecNum[i] + vecNum[j], make_pair(i, j)));
}
}
for (auto iterBg = mapTemp.begin(); iterBg != mapTemp.end(); ++iterBg)
{
int nRemaind = nTarget - iterBg->first;
auto mapRange = mapTemp.equal_range(nRemaind);
for (auto iterRangeBgn = mapRange.first; iterRangeBgn != mapRange.second; ++iterRangeBgn)
{
int nOne = iterBg->second.first;
int nTwo = iterBg->second.second;
int nThree = iterRangeBgn->second.first;
int nFour = iterRangeBgn->second.second;
if (nOne != nThree && nOne != nFour && nTwo != nThree && nTwo != nFour)
{
vector<int> vecTemp = { vecNum[nOne], vecNum[nTwo], vecNum[nThree], vecNum[nFour] };
sort(vecTemp.begin(), vecTemp.end());
vecRes.push_back(vecTemp);
}
}
}
sort(vecRes.begin(), vecRes.end());
vecRes.erase(unique(vecRes.begin(), vecRes.end()), vecRes.end());
return vecRes;
}
备注:
感觉方法不是特别好,后续可能在投入时间在思考,LC Discuss上应该有更高效的方法。欢迎大家指正。
tip:
1、15. 3Sum以及16. 3Sum Closest;
2、unordered_multimap和其他同类型 hash_map区别;
3、equal_range函数;