2.1.10 4Sum
描述
Given an arraySofnintegers, are there elementsa, b, c, andd inSsuch thata+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)• esolutionsetmustnotcontainduplicatequadruplets.
For example, given arrayS = {1 0 -1 0 -2 2}, andtarget = 0.
A solution set is:
(-1, 0, 0, 1)
(-2, -1, 1, 2)
(-2, 0, 0, 2)
分析
先排序,然后左右夹逼,复杂度O(n3),会超时。
可以用一个 hashmap先缓存两个数的和,最终复杂度O(n3)。这个策略也适用于3Sum。
左右夹逼
// LeetCode, 4Sum // 先排序,然后左右夹逼,时间复杂度O(n^3),空间复杂度O(1)class Solution { public:
vector<vector<int>> fourSum(vector<int>& num, int target) { vector<vector<int>> result; if (num.size() < 4) return result; sort(num.begin(), num.end());
auto last = num.end(); for (auto a = num.begin(); a < prev(last, 3); ++a) {
for (auto b = next(a); b < prev(last, 2); ++b) { auto c = next(b); auto d = prev(last); while (c < d) {
if (*a + *b + *c + *d < target) { ++c;
} else if (*a + *b + *c + *d > target) { --d;
} else { result.push_back({ *a, *b, *c, *d }); ++c; --d;
}}
}}
sort(result.begin(), result.end()); result.erase(unique(result.begin(), result.end()), result.end()); return result;
}};
map做缓存
// LeetCode, 4Sum // 用一个hashmap先缓存两个数的和 //时间复杂度,平均O(n^2),最坏O(n^4),空间复杂度O(n^2)class Solution { public:
vector<vector<int> > fourSum(vector<int> &num, int target) { vector<vector<int>> result; if (num.size() < 4) return result; sort(num.begin(), num.end());
unordered_map<int, vector<pair<int, int> > > cache; for (size_t a = 0; a < num.size(); ++a) {
for (size_t b = a + 1; b < num.size(); ++b) { cache[num[a] + num[b]].push_back(pair<int, int>(a, b));
}}
![]()
![]()
for (int c = 0; c < num.size(); ++c) { for (size_t d = c + 1; d < num.size(); ++d) { const int key = target - num[c] - num[d];
if (cache.find(key) == cache.end()) continue;
const auto& vec = cache[key]; for (size_t k = 0; k < vec.size(); ++k) {
if (c <= vec[k].second)continue; //有重叠
result.push_back( { num[vec[k].first], num[vec[k].second], num[c], num[d] });
}}
} sort(result.begin(), result.end()); result.erase(unique(result.begin(), result.end()), result.end()); return vector<vector<int> >(result.begin(), result.end());
}};