LeetCode题解——4Sum
题目:
给定一个数组,找出其中和为0的所有4个数组合,每个组合内的4个数非递降。
解法:
①先排序,然后利用4个指针,前两个遍历,后两个在第二个指针之后的部分里夹逼,时间O(N3)。
②或者利用一个哈希表先保存每两个数的和,然后类似于查找两个数的和等于给定值的过程。
代码:
①
1 class Solution {
2 public:
3 vector<vector<int> > fourSum(vector<int> &num, int target) {
4 vector<vector<int> > result;
5 if(num.size() < 4)
6 return result;
7 sort(num.begin(), num.end()); //先排序
8
9 for(int a = 0; a < num.size() - 3; ++a) //a指向第一个数
10 {
11 if(a > 0 && num[a] == num[a-1])
12 continue;
13
14 for(int b = a + 1; b < num.size() - 2; ++b) //b指向第二个数
15 {
16 if(b > a + 1 && num[b] == num[b-1])
17 continue;
18
19 for(int c = b + 1, d = num.size() - 1; c < d; ) //c指向第三个数
20 {
21 if(c > b + 1 && num[c] == num[c-1])
22 {
23 ++c;
24 continue;
25 }
26 if(d < num.size() - 1 && num[d] == num[d+1])
27 {
28 --d;
29 continue;
30 }
31
32 int sum = num[a] + num[b] + num[c] + num[d];
33 if(sum == target)
34 {
35 result.push_back({num[a], num[b], num[c], num[d]});
36 ++c;
37 --d;
38 }
39 else if(sum < target)
40 ++c;
41 else
42 --d;
43 }
44 }
45 }
46 return result;
47 }
48 };
②
1 class Solution {
2 public:
3 vector<vector<int> > fourSum(vector<int> &num, int target) {
4 vector<vector<int> > result;
5 if(num.size() < 4)
6 return result;
7 sort(num.begin(), num.end()); //先排序
8 unordered_map<int, vector<pair<int, int> > > um; //哈希表,保存值为某一个数的所有数对
9
10 for(int a = 0; a < num.size() - 1; ++a)
11 for(int b = a + 1; b < num.size(); ++b)
12 um[ num[a]+num[b] ].push_back(make_pair(a, b));
13
14 for(int a = 0; a < num.size() - 3; ++a)
15 for(int b = a + 1; b < num.size() - 2; ++b)
16 {
17 vector<pair<int, int> > pv = um[target-num[a]-num[b]];
18
19 for(int i = 0; i < pv.size(); ++i)
20 if(b < pv[i].first) //为了保证4个数有序
21 result.push_back({num[a], num[b], num[pv[i].first], num[pv[i].second]});
22 }
23
24 sort(result.begin(), result.end()); //为了去除结果中的重复元素,先排序
25 result.erase(unique(result.begin(), result.end()), result.end()); //unique+erase去冗余
26 return result;
27 }
28 };