1
1
/*
2
2
Author: Annie Kim, [email protected]
3
3
Date: Apr 20, 2013
4
+ Update: Sep 26, 2013
4
5
Problem: 4Sum
5
6
Difficulty: Medium
6
7
Source: http://leetcode.com/onlinejudge#question_18
19
20
(-2, -1, 1, 2)
20
21
(-2, 0, 0, 2)
21
22
22
- Solution: FourSum = TwoSum + TwoSum .
23
+ Solution: Similar to 3Sum, 2Sum .
23
24
*/
24
25
25
- struct TwoSum
26
- {
27
- int sum;
28
- int first;
29
- int second;
30
- TwoSum (int _first, int _second) {
31
- first = _first;
32
- second = _second;
33
- sum = _first + _second;
34
- }
35
- };
36
- bool increasing (TwoSum i, TwoSum j) { return (i.sum < j.sum ); }
37
-
38
26
class Solution {
39
- private:
40
- vector<vector<int >> res;
41
- map<int , int > count;
42
- vector<int > uni;
43
- vector<TwoSum> sum;
44
-
45
27
public:
46
28
vector<vector<int > > fourSum (vector<int > &num, int target) {
47
- res.clear ();
48
- if (num.size () < 4 ) return res;
49
- UniqueAndCount (num);
50
- buildTwoSum ();
51
- searchResult (target);
52
- return res;
53
- }
54
-
55
- private:
56
- void UniqueAndCount (const vector<int > &num)
57
- {
58
- count.clear ();
59
- uni.clear ();
60
- for (int i = 0 ; i < num.size (); ++i) {
61
- if (count[num[i]] == 0 )
62
- uni.push_back (num[i]);
63
- count[num[i]]++;
64
- }
65
- }
66
-
67
- void buildTwoSum ()
68
- {
69
- sum.clear ();
70
- for (int i = 0 ; i < uni.size (); ++i)
71
- for (int j = i + 1 ; j < uni.size (); ++j)
72
- sum.push_back (TwoSum (uni[i], uni[j]));
73
- // for duplicate numbers
74
- for (map<int ,int >::iterator it = count.begin (); it != count.end (); ++it)
75
- if ((*it).second > 1 )
76
- sum.push_back (TwoSum ((*it).first , (*it).first ));
77
- sort (sum.begin (), sum.end (), increasing);
78
- }
79
-
80
- void searchResult (int target)
81
- {
82
- int i = 0 ; int j = sum.size () - 1 ;
83
- while (i < j)
29
+ int N = num.size ();
30
+ vector<vector<int > > res;
31
+ if (N < 4 ) return res;
32
+ sort (num.begin (), num.end ());
33
+ for (int i = 0 ; i < N; ++i)
84
34
{
85
- int s = sum[i].sum + sum[j].sum ;
86
- if (s == target) {
87
- int m = i, n = j;
88
- while (m < j && sum[m].sum == sum[i].sum ) {
89
- n = j;
90
- while (m < n && sum[n].sum == sum[j].sum )
91
- pushResult (sum[m], sum[n--]);
92
- m++;
35
+ if (i > 0 && num[i] == num[i-1 ]) continue ; // avoid duplicates
36
+ for (int j = i+1 ; j < N; ++j)
37
+ {
38
+ if (j > i+1 && num[j] == num[j-1 ]) continue ; // avoid duplicates
39
+ int twosum = target - num[i] - num[j];
40
+ int l = j + 1 , r = N - 1 ;
41
+ while (l < r)
42
+ {
43
+ int sum = num[l] + num[r];
44
+ if (sum == twosum) {
45
+ vector<int > quadruplet (4 );
46
+ quadruplet[0 ] = num[i];
47
+ quadruplet[1 ] = num[j];
48
+ quadruplet[2 ] = num[l];
49
+ quadruplet[3 ] = num[r];
50
+ res.push_back (quadruplet);
51
+ while (l < r && num[l+1 ] == num[l]) l++; // avoid duplicates
52
+ while (l < r && num[r-1 ] == num[r]) r--; // avoid duplicates
53
+ l++; r--;
54
+ }
55
+ else if (sum < twosum) l++;
56
+ else r--;
93
57
}
94
- i = m;
95
- j = n;
96
- } else if (s < target) {
97
- i++;
98
- } else {
99
- j--;
100
58
}
101
59
}
102
- // for the numbers that have more than 4 copies
103
- for (map<int ,int >::iterator it = count.begin (); it != count.end (); ++it)
104
- if ((*it).second >= 4 && (*it).first * 4 == target)
105
- pushResult (TwoSum ((*it).first , (*it).first ), TwoSum ((*it).first , (*it).first ));
106
- }
107
-
108
- void pushResult (const TwoSum &a, const TwoSum &b)
109
- {
110
- vector<int > quadruplet;
111
- quadruplet.push_back (a.first );
112
- quadruplet.push_back (a.second );
113
- quadruplet.push_back (b.first );
114
- quadruplet.push_back (b.second );
115
- // check counts
116
- map<int , int > used;
117
- for (int i = 0 ; i < quadruplet.size (); ++i)
118
- used[quadruplet[i]]++;
119
- for (map<int , int >::iterator it = used.begin (); it != used.end (); ++it)
120
- if ((*it).second > count[(*it).first ])
121
- return ;
122
- // avoid duplicates
123
- sort (quadruplet.begin (), quadruplet.end ());
124
- if (find (res.begin (), res.end (), quadruplet) == res.end ())
125
- res.push_back (quadruplet);
60
+ return res;
126
61
}
127
- };
62
+ };
0 commit comments