48
48
49
49
** 方法一:排序 + 双指针**
50
50
51
- 该题和 [ 0015.三数之和] ( https://leetcode.cn/problems/3sum/ ) 相似,解法也相似。
51
+ 我们注意到,题目中要求找到不重复的四元组,那么我们可以先对数组进行排序,这样就可以方便地跳过重复的元素。
52
+
53
+ 接下来,我们枚举四元组的前两个元素 $nums[ i] $ 和 $nums[ j] $,其中 $i \lt j$,在枚举的过程中,我们跳过重复的 $nums[ i] $ 和 $nums[ j] $。然后,我们用两个指针 $k$ 和 $l$ 分别指向 $nums[ i] $ 和 $nums[ j] $ 后面的两端,令 $x = nums[ i] + nums[ j] + nums[ k] + nums[ l] $,我们将 $x$ 与 $target$ 比较,进行如下操作:
54
+
55
+ - 如果 $x \lt target$,则更新 $k = k + 1$ 以得到更大的 $x$;
56
+ - 如果 $x \gt target$,则更新 $l = l - 1$ 以得到更小的 $x$;
57
+ - 否则,说明找到了一个四元组 $(nums[ i] , nums[ j] , nums[ k] , nums[ l] )$,将其加入答案,然后我们更新指针 $k$ 和 $l$,并跳过所有重复的元素,防止答案中包含重复的四元组,继续寻找下一个四元组。
52
58
53
59
时间复杂度为 $O(n^3)$,空间复杂度为 $O(\log n)$,其中 $n$ 是数组的长度。
54
60
61
67
``` python
62
68
class Solution :
63
69
def fourSum (self , nums : List[int ], target : int ) -> List[List[int ]]:
64
- n, res = len (nums), []
70
+ n = len (nums)
71
+ ans = []
65
72
if n < 4 :
66
- return []
73
+ return ans
67
74
nums.sort()
68
75
for i in range (n - 3 ):
69
- if i > 0 and nums[i] == nums[i - 1 ]:
76
+ if i and nums[i] == nums[i - 1 ]:
70
77
continue
71
78
for j in range (i + 1 , n - 2 ):
72
79
if j > i + 1 and nums[j] == nums[j - 1 ]:
73
80
continue
74
81
k, l = j + 1 , n - 1
75
82
while k < l:
76
- if nums[i] + nums[j] + nums[k] + nums[l] == target:
77
- res.append([nums[i], nums[j], nums[k], nums[l]])
83
+ x = nums[i] + nums[j] + nums[k] + nums[l]
84
+ if x < target:
78
85
k += 1
86
+ elif x > target:
79
87
l -= 1
80
- while k < n and nums[k] == nums[k - 1 ]:
88
+ else :
89
+ ans.append([nums[i], nums[j], nums[k], nums[l]])
90
+ k, l = k + 1 , l - 1
91
+ while k < l and nums[k] == nums[k - 1 ]:
81
92
k += 1
82
- while l > j and nums[l] == nums[l + 1 ]:
93
+ while k < l and nums[l] == nums[l + 1 ]:
83
94
l -= 1
84
- elif nums[i] + nums[j] + nums[k] + nums[l] < target:
85
- k += 1
86
- else :
87
- l -= 1
88
- return res
95
+ return ans
89
96
```
90
97
91
98
### ** Java**
@@ -96,11 +103,11 @@ class Solution:
96
103
class Solution {
97
104
public List<List<Integer > > fourSum (int [] nums , int target ) {
98
105
int n = nums. length;
106
+ List<List<Integer > > ans = new ArrayList<> ();
99
107
if (n < 4 ) {
100
- return Collections . emptyList() ;
108
+ return ans ;
101
109
}
102
110
Arrays . sort(nums);
103
- List<List<Integer > > res = new ArrayList<> ();
104
111
for (int i = 0 ; i < n - 3 ; ++ i) {
105
112
if (i > 0 && nums[i] == nums[i - 1 ]) {
106
113
continue ;
@@ -111,25 +118,24 @@ class Solution {
111
118
}
112
119
int k = j + 1 , l = n - 1 ;
113
120
while (k < l) {
114
- if ( nums[i] + nums[j] + nums[k] + nums[l] == target) {
115
- res . add( Arrays . asList(nums[i], nums[j], nums[k], nums[l]));
121
+ long x = ( long ) nums[i] + nums[j] + nums[k] + nums[l];
122
+ if (x < target) {
116
123
++ k;
124
+ } else if (x > target) {
117
125
-- l;
118
- while (k < n && nums[k] == nums[k - 1 ]) {
126
+ } else {
127
+ ans. add(List . of(nums[i], nums[j], nums[k++ ], nums[l-- ]));
128
+ while (k < l && nums[k] == nums[k - 1 ]) {
119
129
++ k;
120
130
}
121
- while (l > j && nums[l] == nums[l + 1 ]) {
131
+ while (k < l && nums[l] == nums[l + 1 ]) {
122
132
-- l;
123
133
}
124
- } else if (nums[i] + nums[j] + nums[k] + nums[l] < target) {
125
- ++ k;
126
- } else {
127
- -- l;
128
134
}
129
135
}
130
136
}
131
137
}
132
- return res ;
138
+ return ans ;
133
139
}
134
140
}
135
141
```
@@ -141,69 +147,82 @@ class Solution {
141
147
public:
142
148
vector<vector<int >> fourSum(vector<int >& nums, int target) {
143
149
int n = nums.size();
150
+ vector<vector<int > > ans;
144
151
if (n < 4) {
145
- return {} ;
152
+ return ans ;
146
153
}
147
154
sort(nums.begin(), nums.end());
148
- vector<vector<int >> res;
149
155
for (int i = 0; i < n - 3; ++i) {
150
- if (i > 0 && nums[ i] == nums[ i - 1] ) continue;
156
+ if (i && nums[ i] == nums[ i - 1] ) {
157
+ continue;
158
+ }
151
159
for (int j = i + 1; j < n - 2; ++j) {
152
- if (j > i + 1 && nums[ j] == nums[ j - 1] ) continue;
160
+ if (j > i + 1 && nums[ j] == nums[ j - 1] ) {
161
+ continue;
162
+ }
153
163
int k = j + 1, l = n - 1;
154
164
while (k < l) {
155
- if ( nums[ i] + nums[ j] == target - nums[ k] - nums[ l] ) {
156
- res.push_back({nums [ i ] , nums [ j ] , nums [ k ] , nums [ l ] });
165
+ long long x = (long long) nums[ i] + nums[ j] + nums[ k] + nums[ l] ;
166
+ if (x < target) {
157
167
++k;
168
+ } else if (x > target) {
158
169
--l;
159
- while (k < n && nums[ k] == nums[ k - 1] ) ++k;
160
- while (l > j && nums[ l] == nums[ l + 1] ) --l;
161
- } else if (nums[ i] + nums[ j] < target - nums[ k] - nums[ l] ) {
162
- ++k;
163
170
} else {
164
- --l;
171
+ ans.push_back({nums[ i] , nums[ j] , nums[ k++] , nums[ l--] });
172
+ while (k < l && nums[ k] == nums[ k - 1] ) {
173
+ ++k;
174
+ }
175
+ while (k < l && nums[ l] == nums[ l + 1] ) {
176
+ --l;
177
+ }
165
178
}
166
179
}
167
180
}
168
181
}
169
- return res ;
182
+ return ans ;
170
183
}
171
184
};
172
185
```
173
186
174
187
### **Go**
175
188
176
189
```go
177
- func fourSum(nums []int, target int) [][]int {
178
- ans, n := [][]int{}, len(nums)
190
+ func fourSum(nums []int, target int) (ans [][]int) {
191
+ n := len(nums)
192
+ if n < 4 {
193
+ return
194
+ }
179
195
sort.Ints(nums)
180
- for i := 0; i < n; i++ {
181
- for j := i + 1; j < n; j++ {
182
- for l, r := j+1, n-1; l < r; {
183
- if nums[i]+nums[j]+nums[l]+nums[r] == target {
184
- ans = append(ans, []int{nums[i], nums[j], nums[l], nums[r]})
185
- l, r = l+1, r-1
186
- for l < r && nums[l] == nums[l-1] {
187
- l++
196
+ for i := 0; i < n-3; i++ {
197
+ if i > 0 && nums[i] == nums[i-1] {
198
+ continue
199
+ }
200
+ for j := i + 1; j < n-2; j++ {
201
+ if j > i+1 && nums[j] == nums[j-1] {
202
+ continue
203
+ }
204
+ k, l := j+1, n-1
205
+ for k < l {
206
+ x := nums[i] + nums[j] + nums[k] + nums[l]
207
+ if x < target {
208
+ k++
209
+ } else if x > target {
210
+ l--
211
+ } else {
212
+ ans = append(ans, []int{nums[i], nums[j], nums[k], nums[l]})
213
+ k++
214
+ l--
215
+ for k < l && nums[k] == nums[k-1] {
216
+ k++
188
217
}
189
- for l < r && nums[r ] == nums[r +1] {
190
- r --
218
+ for k < l && nums[l ] == nums[l +1] {
219
+ l --
191
220
}
192
- } else if nums[i]+nums[j]+nums[l]+nums[r] < target {
193
- l++
194
- } else {
195
- r--
196
221
}
197
222
}
198
- for j+1 < n && nums[j+1] == nums[j] {
199
- j++
200
- }
201
- }
202
- for i+1 < n && nums[i+1] == nums[i] {
203
- i++
204
223
}
205
224
}
206
- return ans
225
+ return
207
226
}
208
227
```
209
228
@@ -217,34 +236,126 @@ func fourSum(nums []int, target int) [][]int {
217
236
*/
218
237
var fourSum = function (nums , target ) {
219
238
const n = nums .length ;
220
- if (n < 4 ) return [];
221
- let res = [];
239
+ const ans = [];
240
+ if (n < 4 ) {
241
+ return ans;
242
+ }
222
243
nums .sort ((a , b ) => a - b);
223
244
for (let i = 0 ; i < n - 3 ; ++ i) {
224
- if (i > 0 && nums[i] == nums[i - 1 ]) continue ;
245
+ if (i > 0 && nums[i] === nums[i - 1 ]) {
246
+ continue ;
247
+ }
225
248
for (let j = i + 1 ; j < n - 2 ; ++ j) {
226
- if (j > i + 1 && nums[j] == nums[j - 1 ]) continue ;
227
- let k = j + 1 ;
228
- let l = n - 1 ;
249
+ if (j > i + 1 && nums[j] === nums[j - 1 ]) {
250
+ continue ;
251
+ }
252
+ let [k, l] = [j + 1 , n - 1 ];
229
253
while (k < l) {
230
- if ( nums[i] + nums[j] + nums[k] + nums[l] == target) {
231
- res . push ([nums[i], nums[j], nums[k], nums[l]]);
254
+ const x = nums[i] + nums[j] + nums[k] + nums[l];
255
+ if (x < target) {
232
256
++ k;
257
+ } else if (x > target) {
233
258
-- l;
234
- while (k < n && nums[k] == nums[k - 1 ]) ++ k;
235
- while (l > j && nums[l] == nums[l + 1 ]) -- l;
236
- } else if (nums[i] + nums[j] + nums[k] + nums[l] < target) {
237
- ++ k;
238
259
} else {
239
- -- l;
260
+ ans .push ([nums[i], nums[j], nums[k++ ], nums[l-- ]]);
261
+ while (k < l && nums[k] === nums[k - 1 ]) {
262
+ ++ k;
263
+ }
264
+ while (k < l && nums[l] === nums[l + 1 ]) {
265
+ -- l;
266
+ }
240
267
}
241
268
}
242
269
}
243
270
}
244
- return res ;
271
+ return ans ;
245
272
};
246
273
```
247
274
275
+ ### ** TypeScript**
276
+
277
+ ``` ts
278
+ function fourSum(nums : number [], target : number ): number [][] {
279
+ const n = nums .length ;
280
+ const ans: number [][] = [];
281
+ if (n < 4 ) {
282
+ return ans ;
283
+ }
284
+ nums .sort ((a , b ) => a - b );
285
+ for (let i = 0 ; i < n - 3 ; ++ i ) {
286
+ if (i > 0 && nums [i ] === nums [i - 1 ]) {
287
+ continue ;
288
+ }
289
+ for (let j = i + 1 ; j < n - 2 ; ++ j ) {
290
+ if (j > i + 1 && nums [j ] === nums [j - 1 ]) {
291
+ continue ;
292
+ }
293
+ let [k, l] = [j + 1 , n - 1 ];
294
+ while (k < l ) {
295
+ const x = nums [i ] + nums [j ] + nums [k ] + nums [l ];
296
+ if (x < target ) {
297
+ ++ k ;
298
+ } else if (x > target ) {
299
+ -- l ;
300
+ } else {
301
+ ans .push ([nums [i ], nums [j ], nums [k ++ ], nums [l -- ]]);
302
+ while (k < l && nums [k ] === nums [k - 1 ]) {
303
+ ++ k ;
304
+ }
305
+ while (k < l && nums [l ] === nums [l + 1 ]) {
306
+ -- l ;
307
+ }
308
+ }
309
+ }
310
+ }
311
+ }
312
+ return ans ;
313
+ }
314
+ ```
315
+
316
+ ### ** C#**
317
+
318
+ ``` cs
319
+ public class Solution {
320
+ public IList <IList <int >> FourSum (int [] nums , int target ) {
321
+ int n = nums .Length ;
322
+ var ans = new List <IList <int >>();
323
+ if (n < 4 ) {
324
+ return ans ;
325
+ }
326
+ Array .Sort (nums );
327
+ for (int i = 0 ; i < n - 3 ; ++ i ) {
328
+ if (i > 0 && nums [i ] == nums [i - 1 ]) {
329
+ continue ;
330
+ }
331
+ for (int j = i + 1 ; j < n - 2 ; ++ j ) {
332
+ if (j > i + 1 && nums [j ] == nums [j - 1 ]) {
333
+ continue ;
334
+ }
335
+ int k = j + 1 , l = n - 1 ;
336
+ while (k < l ) {
337
+ long x = (long ) nums [i ] + nums [j ] + nums [k ] + nums [l ];
338
+ if (x < target ) {
339
+ ++ k ;
340
+ } else if (x > target ) {
341
+ -- l ;
342
+ } else {
343
+ ans .Add (new List <int > {nums [i ], nums [j ], nums [k ++ ], nums [l -- ]});
344
+ while (k < l && nums [k ] == nums [k - 1 ]) {
345
+ ++ k ;
346
+ }
347
+ while (k < l && nums [l ] == nums [l + 1 ]) {
348
+ -- l ;
349
+ }
350
+ }
351
+ }
352
+ }
353
+ }
354
+ return ans ;
355
+ }
356
+ }
357
+ ```
358
+
248
359
### ** ...**
249
360
250
361
```
0 commit comments