Skip to content

Commit 78dbce6

Browse files
authored
feat: add solutions to lc problem: No.0018 (doocs#1207)
No.0018.4Sum
1 parent f220948 commit 78dbce6

File tree

9 files changed

+588
-341
lines changed

9 files changed

+588
-341
lines changed

solution/0000-0099/0018.4Sum/README.md

Lines changed: 184 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,13 @@
4848

4949
**方法一:排序 + 双指针**
5050

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$,并跳过所有重复的元素,防止答案中包含重复的四元组,继续寻找下一个四元组。
5258

5359
时间复杂度为 $O(n^3)$,空间复杂度为 $O(\log n)$,其中 $n$ 是数组的长度。
5460

@@ -61,31 +67,32 @@
6167
```python
6268
class Solution:
6369
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
64-
n, res = len(nums), []
70+
n = len(nums)
71+
ans = []
6572
if n < 4:
66-
return []
73+
return ans
6774
nums.sort()
6875
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]:
7077
continue
7178
for j in range(i + 1, n - 2):
7279
if j > i + 1 and nums[j] == nums[j - 1]:
7380
continue
7481
k, l = j + 1, n - 1
7582
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:
7885
k += 1
86+
elif x > target:
7987
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]:
8192
k += 1
82-
while l > j and nums[l] == nums[l + 1]:
93+
while k < l and nums[l] == nums[l + 1]:
8394
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
8996
```
9097

9198
### **Java**
@@ -96,11 +103,11 @@ class Solution:
96103
class Solution {
97104
public List<List<Integer>> fourSum(int[] nums, int target) {
98105
int n = nums.length;
106+
List<List<Integer>> ans = new ArrayList<>();
99107
if (n < 4) {
100-
return Collections.emptyList();
108+
return ans;
101109
}
102110
Arrays.sort(nums);
103-
List<List<Integer>> res = new ArrayList<>();
104111
for (int i = 0; i < n - 3; ++i) {
105112
if (i > 0 && nums[i] == nums[i - 1]) {
106113
continue;
@@ -111,25 +118,24 @@ class Solution {
111118
}
112119
int k = j + 1, l = n - 1;
113120
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) {
116123
++k;
124+
} else if (x > target) {
117125
--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]) {
119129
++k;
120130
}
121-
while (l > j && nums[l] == nums[l + 1]) {
131+
while (k < l && nums[l] == nums[l + 1]) {
122132
--l;
123133
}
124-
} else if (nums[i] + nums[j] + nums[k] + nums[l] < target) {
125-
++k;
126-
} else {
127-
--l;
128134
}
129135
}
130136
}
131137
}
132-
return res;
138+
return ans;
133139
}
134140
}
135141
```
@@ -141,69 +147,82 @@ class Solution {
141147
public:
142148
vector<vector<int>> fourSum(vector<int>& nums, int target) {
143149
int n = nums.size();
150+
vector<vector<int> > ans;
144151
if (n < 4) {
145-
return {};
152+
return ans;
146153
}
147154
sort(nums.begin(), nums.end());
148-
vector<vector<int>> res;
149155
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+
}
151159
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+
}
153163
int k = j + 1, l = n - 1;
154164
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) {
157167
++k;
168+
} else if (x > target) {
158169
--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;
163170
} 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+
}
165178
}
166179
}
167180
}
168181
}
169-
return res;
182+
return ans;
170183
}
171184
};
172185
```
173186
174187
### **Go**
175188
176189
```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+
}
179195
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++
188217
}
189-
for l < r && nums[r] == nums[r+1] {
190-
r--
218+
for k < l && nums[l] == nums[l+1] {
219+
l--
191220
}
192-
} else if nums[i]+nums[j]+nums[l]+nums[r] < target {
193-
l++
194-
} else {
195-
r--
196221
}
197222
}
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++
204223
}
205224
}
206-
return ans
225+
return
207226
}
208227
```
209228

@@ -217,34 +236,126 @@ func fourSum(nums []int, target int) [][]int {
217236
*/
218237
var fourSum = function (nums, target) {
219238
const n = nums.length;
220-
if (n < 4) return [];
221-
let res = [];
239+
const ans = [];
240+
if (n < 4) {
241+
return ans;
242+
}
222243
nums.sort((a, b) => a - b);
223244
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+
}
225248
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];
229253
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) {
232256
++k;
257+
} else if (x > target) {
233258
--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;
238259
} 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+
}
240267
}
241268
}
242269
}
243270
}
244-
return res;
271+
return ans;
245272
};
246273
```
247274

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+
248359
### **...**
249360

250361
```

0 commit comments

Comments
 (0)