Skip to content

Commit 3bfd2df

Browse files
committed
15. 3Sum
```Solution.c /** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array. * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). */ int cmp(const void* a, const void* b) { return *(int*)a - *(int*)b; } int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) { qsort(nums, numsSize, sizeof(int), cmp); int capacity = 1000, count = 0; int** res = malloc(capacity * sizeof(int*)); *returnColumnSizes = malloc(capacity * sizeof(int)); for (int i = 0; i < numsSize - 2; ++i) { if (i > 0 && nums[i] == nums[i - 1]) continue; int l = i + 1, r = numsSize - 1; while (l < r) { int sum = nums[i] + nums[l] + nums[r]; if (sum < 0) l++; else if (sum > 0) r--; else { if (count == capacity) { capacity *= 2; res = realloc(res, capacity * sizeof(int*)); *returnColumnSizes = realloc(*returnColumnSizes, capacity * sizeof(int)); } res[count] = malloc(3 * sizeof(int)); res[count][0] = nums[i]; res[count][1] = nums[l]; res[count][2] = nums[r]; (*returnColumnSizes)[count++] = 3; while (l < r && nums[l] == nums[l + 1]) l++; while (l < r && nums[r] == nums[r - 1]) r--; l++; r--; } } } *returnSize = count; return res; } ``` ```Solution.cpp class Solution { public: vector<vector<int>> threeSum(vector<int>& nums) { vector<vector<int>> res; sort(nums.begin(), nums.end()); int n = nums.size(); for (int i = 0; i < n - 2; ++i) { if (i > 0 && nums[i] == nums[i - 1]) continue; int l = i + 1, r = n - 1; while (l < r) { int s = nums[i] + nums[l] + nums[r]; if (s < 0) ++l; else if (s > 0) --r; else { res.push_back({nums[i], nums[l], nums[r]}); while (l < r && nums[l] == nums[l + 1]) ++l; while (l < r && nums[r] == nums[r - 1]) --r; ++l; --r; } } } return res; } }; ``` ```Solution.cs public class Solution { public IList<IList<int>> ThreeSum(int[] nums) { Array.Sort(nums); var res = new List<IList<int>>(); for (int i = 0; i < nums.Length - 2; i++) { if (i > 0 && nums[i] == nums[i - 1]) continue; int l = i + 1, r = nums.Length - 1; while (l < r) { int sum = nums[i] + nums[l] + nums[r]; if (sum < 0) l++; else if (sum > 0) r--; else { res.Add(new List<int> { nums[i], nums[l], nums[r] }); while (l < r && nums[l] == nums[l + 1]) l++; while (l < r && nums[r] == nums[r - 1]) r--; l++; r--; } } } return res; } } ``` ```Solution.dart class Solution { List<List<int>> threeSum(List<int> nums) { nums.sort(); List<List<int>> res = []; for (int i = 0; i < nums.length - 2; i++) { if (i > 0 && nums[i] == nums[i - 1]) continue; int l = i + 1, r = nums.length - 1; while (l < r) { int sum = nums[i] + nums[l] + nums[r]; if (sum < 0) { l++; } else if (sum > 0) { r--; } else { res.add([nums[i], nums[l], nums[r]]); while (l < r && nums[l] == nums[l + 1]) l++; while (l < r && nums[r] == nums[r - 1]) r--; l++; r--; } } } return res; } } ``` ```Solution.erl -spec three_sum([integer()]) -> [[integer()]]. three_sum(Nums) -> Sorted = lists:sort(Nums), Tuple = list_to_tuple(Sorted), Len = tuple_size(Tuple), three_sum_loop(Tuple, 1, Len, []). three_sum_loop(_T, I, Len, Acc) when I > Len - 2 -> lists:reverse(Acc); three_sum_loop(T, I, Len, Acc) -> A = element(I, T), case (I > 1) andalso (A =:= element(I - 1, T)) of true -> three_sum_loop(T, I + 1, Len, Acc); false -> Acc1 = two_sum(T, I, I + 1, Len, A, Acc), three_sum_loop(T, I + 1, Len, Acc1) end. two_sum(_T, _I, Left, Right, _A, Acc) when Left >= Right -> Acc; two_sum(T, I, Left, Right, A, Acc) -> B = element(Left, T), C = element(Right, T), Sum = A + B + C, case Sum of 0 -> Triplet = [A, B, C], NewAcc = [Triplet | Acc], NewLeft = skip_forward(T, B, Left + 1, Right), NewRight = skip_backward(T, C, NewLeft, Right - 1), two_sum(T, I, NewLeft, NewRight, A, NewAcc); _ when Sum < 0 -> two_sum(T, I, Left + 1, Right, A, Acc); _ -> two_sum(T, I, Left, Right - 1, A, Acc) end. skip_forward(T, Val, Pos, Right) when Pos =< Right, element(Pos, T) =:= Val -> skip_forward(T, Val, Pos + 1, Right); skip_forward(_T, _Val, Pos, _Right) -> Pos. skip_backward(T, Val, Left, Pos) when Pos >= Left, element(Pos, T) =:= Val -> skip_backward(T, Val, Left, Pos - 1); skip_backward(_T, _Val, _Left, Pos) -> Pos. ``` ```Solution.ex defmodule Solution do @SPEC three_sum(nums :: [integer]) :: [[integer]] def three_sum(nums) do nums = List.to_tuple(Enum.sort(nums)) do_three_sum(nums, 0, tuple_size(nums), []) end defp do_three_sum(nums, i, len, acc) do val_i = elem(nums, i) cond do val_i > 0 or i > len - 3 -> acc i == 0 or elem(nums, i - 1) != val_i -> acc = find_triplets(nums, i, i + 1, len - 1, acc) do_three_sum(nums, i + 1, len, acc) true -> do_three_sum(nums, i + 1, len, acc) end end defp find_triplets(_nums, _i, l, r, acc) when l >= r, do: acc defp find_triplets(nums, i, l, r, acc) do val_i = elem(nums, i) val_l = elem(nums, l) val_r = elem(nums, r) sum = val_i + val_l + val_r cond do sum > 0 -> find_triplets(nums, i, l, r - 1, acc) sum < 0 -> find_triplets(nums, i, l + 1, r, acc) true -> acc = [[val_i, val_l, val_r] | acc] l = grow_from_left(nums, l + 1, r, val_l) r = shrink_from_right(nums, l, r - 1, val_r) find_triplets(nums, i, l, r, acc) end end defp shrink_from_right(nums, l, r, prev_val_r) do cond do r <= l or elem(nums, r) != prev_val_r -> r true -> shrink_from_right(nums, l, r - 1, prev_val_r) end end defp grow_from_left(nums, l, r, prev_val_l) do cond do l >= r or elem(nums, l) != prev_val_l -> l true -> grow_from_left(nums, l + 1, r, prev_val_l) end end end ``` ```Solution.go func threeSum(nums []int) [][]int { sort.Ints(nums) res := [][]int{} for i := 0; i < len(nums)-2; i++ { if i > 0 && nums[i] == nums[i-1] { continue } l, r := i+1, len(nums)-1 for l < r { sum := nums[i] + nums[l] + nums[r] if sum < 0 { l++ } else if sum > 0 { r-- } else { res = append(res, []int{nums[i], nums[l], nums[r]}) for l < r && nums[l] == nums[l+1] { l++ } for l < r && nums[r] == nums[r-1] { r-- } l++ r-- } } } return res } ``` ```Solution.java class Solution { public List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> res = new ArrayList<>(); Arrays.sort(nums); for (int i = 0; i < nums.length - 2; ++i) { if (i > 0 && nums[i] == nums[i - 1]) continue; int l = i + 1, r = nums.length - 1; while (l < r) { int sum = nums[i] + nums[l] + nums[r]; if (sum < 0) l++; else if (sum > 0) r--; else { res.add(Arrays.asList(nums[i], nums[l], nums[r])); while (l < r && nums[l] == nums[l + 1]) l++; while (l < r && nums[r] == nums[r - 1]) r--; l++; r--; } } } return res; } } ``` ```Solution.js /** * @param {number[]} nums * @return {number[][]} */ var threeSum = function(nums) { nums.sort((a, b) => a - b); const res = []; for (let i = 0; i < nums.length - 2; i++) { if (i > 0 && nums[i] === nums[i - 1]) continue; let l = i + 1, r = nums.length - 1; while (l < r) { const sum = nums[i] + nums[l] + nums[r]; if (sum < 0) l++; else if (sum > 0) r--; else { res.push([nums[i], nums[l], nums[r]]); while (l < r && nums[l] === nums[l + 1]) l++; while (l < r && nums[r] === nums[r - 1]) r--; l++; r--; } } } return res; }; ``` ```Solution.kt class Solution { fun threeSum(nums: IntArray): List<List<Int>> { nums.sort() val res = mutableListOf<List<Int>>() for (i in 0 until nums.size - 2) { if (i > 0 && nums[i] == nums[i - 1]) continue var l = i + 1 var r = nums.size - 1 while (l < r) { val sum = nums[i] + nums[l] + nums[r] when { sum < 0 -> l++ sum > 0 -> r-- else -> { res.add(listOf(nums[i], nums[l], nums[r])) while (l < r && nums[l] == nums[l + 1]) l++ while (l < r && nums[r] == nums[r - 1]) r-- l++ r-- } } } } return res } } ``` ```Solution.php class Solution { /** * @param Integer[] $nums * @return Integer[][] */ function threeSum($nums) { sort($nums); $res = []; $n = count($nums); for ($i = 0; $i < $n - 2; $i++) { if ($i > 0 && $nums[$i] == $nums[$i - 1]) continue; $l = $i + 1; $r = $n - 1; while ($l < $r) { $sum = $nums[$i] + $nums[$l] + $nums[$r]; if ($sum < 0) $l++; else if ($sum > 0) $r--; else { $res[] = [$nums[$i], $nums[$l], $nums[$r]]; while ($l < $r && $nums[$l] == $nums[$l + 1]) $l++; while ($l < $r && $nums[$r] == $nums[$r - 1]) $r--; $l++; $r--; } } } return $res; } } ``` ```Solution.py class Solution: def threeSum(self, nums): res = [] nums.sort() for i in range(len(nums) - 2): if i > 0 and nums[i] == nums[i - 1]: continue l, r = i + 1, len(nums) - 1 while l < r: total = nums[i] + nums[l] + nums[r] if total < 0: l += 1 elif total > 0: r -= 1 else: res.append([nums[i], nums[l], nums[r]]) while l < r and nums[l] == nums[l + 1]: l += 1 while l < r and nums[r] == nums[r - 1]: r -= 1 l += 1; r -= 1 return res ``` ```Solution.rb def three_sum(nums) nums.sort! res = [] (0...nums.length - 2).each do |i| next if i > 0 && nums[i] == nums[i - 1] l, r = i + 1, nums.length - 1 while l < r sum = nums[i] + nums[l] + nums[r] if sum < 0 l += 1 elsif sum > 0 r -= 1 else res << [nums[i], nums[l], nums[r]] l += 1 r -= 1 l += 1 while l < r && nums[l] == nums[l - 1] r -= 1 while l < r && nums[r] == nums[r + 1] end end end res end ``` ```Solution.rkt (define/contract (three-sum nums) (-> (listof exact-integer?) (listof (listof exact-integer?))) (define sorted (sort nums <)) (define sorted-vec (list->vector sorted)) (define len (vector-length sorted-vec)) (define (loop i acc) (if (>= i (- len 2)) (reverse acc) (if (and (> i 0) (= (vector-ref sorted-vec i) (vector-ref sorted-vec (- i 1)))) (loop (+ i 1) acc) (let two-pointer ([l (+ i 1)] [r (- len 1)] [acc acc]) (if (>= l r) (loop (+ i 1) acc) (let* ([a (vector-ref sorted-vec i)] [b (vector-ref sorted-vec l)] [c (vector-ref sorted-vec r)] [sum (+ a b c)]) (cond [(< sum 0) (two-pointer (+ l 1) r acc)] [(> sum 0) (two-pointer l (- r 1) acc)] [else (define new-acc (cons (list a b c) acc)) (define (skip-left l) (let loop-l ([l l]) (if (and (< (+ l 1) r) (= (vector-ref sorted-vec l) (vector-ref sorted-vec (+ l 1)))) (loop-l (+ l 1)) (+ l 1)))) (define (skip-right r) (let loop-r ([r r]) (if (and (> (- r 1) l) (= (vector-ref sorted-vec r) (vector-ref sorted-vec (- r 1)))) (loop-r (- r 1)) (- r 1)))) (two-pointer (skip-left l) (skip-right r) new-acc)]))))))) (loop 0 '())) ``` ```Solution.rs impl Solution { pub fn three_sum(mut nums: Vec<i32>) -> Vec<Vec<i32>> { nums.sort(); let mut res = vec![]; for i in 0..nums.len() { if i > 0 && nums[i] == nums[i - 1] { continue; } let (mut l, mut r) = (i + 1, nums.len() - 1); while l < r { let sum = nums[i] + nums[l] + nums[r]; if sum < 0 { l += 1; } else if sum > 0 { r -= 1; } else { res.push(vec![nums[i], nums[l], nums[r]]); while l < r && nums[l] == nums[l + 1] { l += 1; } while l < r && nums[r] == nums[r - 1] { r -= 1; } l += 1; r -= 1; } } } res } } ``` ```Solution.scala object Solution { def threeSum(nums: Array[Int]): List[List[Int]] = { val sorted = nums.sorted var res = List[List[Int]]() for (i <- 0 until sorted.length - 2) { if (i == 0 || sorted(i) != sorted(i - 1)) { var l = i + 1 var r = sorted.length - 1 while (l < r) { val sum = sorted(i) + sorted(l) + sorted(r) if (sum < 0) l += 1 else if (sum > 0) r -= 1 else { res ::= List(sorted(i), sorted(l), sorted(r)) while (l < r && sorted(l) == sorted(l + 1)) l += 1 while (l < r && sorted(r) == sorted(r - 1)) r -= 1 l += 1 r -= 1 } } } } res } } ``` ```Solution.swift class Solution { func threeSum(_ nums: [Int]) -> [[Int]] { let nums = nums.sorted() var res = [[Int]]() for i in 0..<nums.count - 2 { if i > 0 && nums[i] == nums[i - 1] { continue } var l = i + 1, r = nums.count - 1 while l < r { let sum = nums[i] + nums[l] + nums[r] if sum < 0 { l += 1 } else if sum > 0 { r -= 1 } else { res.append([nums[i], nums[l], nums[r]]) while l < r && nums[l] == nums[l + 1] { l += 1 } while l < r && nums[r] == nums[r - 1] { r -= 1 } l += 1 r -= 1 } } } return res } } ``` ```Solution.ts function threeSum(nums: number[]): number[][] { nums.sort((a, b) => a - b); const res: number[][] = []; for (let i = 0; i < nums.length - 2; i++) { if (i > 0 && nums[i] === nums[i - 1]) continue; let l = i + 1, r = nums.length - 1; while (l < r) { const sum = nums[i] + nums[l] + nums[r]; if (sum < 0) l++; else if (sum > 0) r--; else { res.push([nums[i], nums[l], nums[r]]); while (l < r && nums[l] === nums[l + 1]) l++; while (l < r && nums[r] === nums[r - 1]) r--; l++; r--; } } } return res; } ```
1 parent ac63d1e commit 3bfd2df

19 files changed

+536
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# [**15. 3Sum**](https://leetcode.com/problems/3sum/description/)
2+
3+
Given an integer array nums, return all the triplets `[nums[i]`, `nums[j]`, `nums[k]]` such that `i != j`, `i != k`, and `j != k`, and `nums[i] + nums[j] + nums[k] == 0`.
4+
5+
Notice that the solution set must not contain duplicate triplets
6+
7+
#### **Example 1:**
8+
```md
9+
Input: nums = [-1,0,1,2,-1,-4]
10+
Output: [[-1,-1,2],[-1,0,1]]
11+
Explanation:
12+
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0.
13+
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0.
14+
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0.
15+
The distinct triplets are [-1,0,1] and [-1,-1,2].
16+
Notice that the order of the output and the order of the triplets does not matter.
17+
```
18+
19+
#### **Example 2:**
20+
```md
21+
Input: nums = [0,1,1]
22+
Output: []
23+
Explanation: The only possible triplet does not sum up to 0.
24+
```
25+
26+
#### **Example 3:**
27+
```md
28+
Input: nums = [0,0,0]
29+
Output: [[0,0,0]]
30+
Explanation: The only possible triplet sums up to 0.
31+
```
32+
33+
#### **Constraints:**
34+
> - `3 <= nums.length <= 3000`
35+
> - `-10⁵ <= nums[i] <= 10⁵`
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Return an array of arrays of size *returnSize.
3+
* The sizes of the arrays are returned as *returnColumnSizes array.
4+
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
5+
*/
6+
int cmp(const void* a, const void* b) { return *(int*)a - *(int*)b; }
7+
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
8+
qsort(nums, numsSize, sizeof(int), cmp);
9+
int capacity = 1000, count = 0;
10+
int** res = malloc(capacity * sizeof(int*));
11+
*returnColumnSizes = malloc(capacity * sizeof(int));
12+
for (int i = 0; i < numsSize - 2; ++i) {
13+
if (i > 0 && nums[i] == nums[i - 1]) continue;
14+
int l = i + 1, r = numsSize - 1;
15+
while (l < r) {
16+
int sum = nums[i] + nums[l] + nums[r];
17+
if (sum < 0) l++;
18+
else if (sum > 0) r--;
19+
else {
20+
if (count == capacity) {
21+
capacity *= 2;
22+
res = realloc(res, capacity * sizeof(int*));
23+
*returnColumnSizes = realloc(*returnColumnSizes, capacity * sizeof(int));
24+
}
25+
res[count] = malloc(3 * sizeof(int));
26+
res[count][0] = nums[i]; res[count][1] = nums[l]; res[count][2] = nums[r];
27+
(*returnColumnSizes)[count++] = 3;
28+
while (l < r && nums[l] == nums[l + 1]) l++;
29+
while (l < r && nums[r] == nums[r - 1]) r--;
30+
l++; r--;
31+
}
32+
}
33+
}
34+
*returnSize = count;
35+
return res;
36+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
public:
3+
vector<vector<int>> threeSum(vector<int>& nums) {
4+
vector<vector<int>> res;
5+
sort(nums.begin(), nums.end());
6+
int n = nums.size();
7+
for (int i = 0; i < n - 2; ++i) {
8+
if (i > 0 && nums[i] == nums[i - 1]) continue;
9+
int l = i + 1, r = n - 1;
10+
while (l < r) {
11+
int s = nums[i] + nums[l] + nums[r];
12+
if (s < 0) ++l;
13+
else if (s > 0) --r;
14+
else {
15+
res.push_back({nums[i], nums[l], nums[r]});
16+
while (l < r && nums[l] == nums[l + 1]) ++l;
17+
while (l < r && nums[r] == nums[r - 1]) --r;
18+
++l; --r;
19+
}
20+
}
21+
}
22+
return res;
23+
}
24+
};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
public class Solution {
2+
public IList<IList<int>> ThreeSum(int[] nums) {
3+
Array.Sort(nums);
4+
var res = new List<IList<int>>();
5+
for (int i = 0; i < nums.Length - 2; i++) {
6+
if (i > 0 && nums[i] == nums[i - 1]) continue;
7+
int l = i + 1, r = nums.Length - 1;
8+
while (l < r) {
9+
int sum = nums[i] + nums[l] + nums[r];
10+
if (sum < 0) l++;
11+
else if (sum > 0) r--;
12+
else {
13+
res.Add(new List<int> { nums[i], nums[l], nums[r] });
14+
while (l < r && nums[l] == nums[l + 1]) l++;
15+
while (l < r && nums[r] == nums[r - 1]) r--;
16+
l++; r--;
17+
}
18+
}
19+
}
20+
return res;
21+
}
22+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class Solution {
2+
List<List<int>> threeSum(List<int> nums) {
3+
nums.sort();
4+
List<List<int>> res = [];
5+
for (int i = 0; i < nums.length - 2; i++) {
6+
if (i > 0 && nums[i] == nums[i - 1]) continue;
7+
int l = i + 1, r = nums.length - 1;
8+
while (l < r) {
9+
int sum = nums[i] + nums[l] + nums[r];
10+
if (sum < 0) {
11+
l++;
12+
} else if (sum > 0) {
13+
r--;
14+
} else {
15+
res.add([nums[i], nums[l], nums[r]]);
16+
while (l < r && nums[l] == nums[l + 1]) l++;
17+
while (l < r && nums[r] == nums[r - 1]) r--;
18+
l++;
19+
r--;
20+
}
21+
}
22+
}
23+
return res;
24+
}
25+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
-spec three_sum([integer()]) -> [[integer()]].
2+
three_sum(Nums) ->
3+
Sorted = lists:sort(Nums),
4+
Tuple = list_to_tuple(Sorted),
5+
Len = tuple_size(Tuple),
6+
three_sum_loop(Tuple, 1, Len, []).
7+
three_sum_loop(_T, I, Len, Acc) when I > Len - 2 ->
8+
lists:reverse(Acc);
9+
three_sum_loop(T, I, Len, Acc) ->
10+
A = element(I, T),
11+
case (I > 1) andalso (A =:= element(I - 1, T)) of
12+
true ->
13+
three_sum_loop(T, I + 1, Len, Acc);
14+
false ->
15+
Acc1 = two_sum(T, I, I + 1, Len, A, Acc),
16+
three_sum_loop(T, I + 1, Len, Acc1)
17+
end.
18+
two_sum(_T, _I, Left, Right, _A, Acc) when Left >= Right ->
19+
Acc;
20+
two_sum(T, I, Left, Right, A, Acc) ->
21+
B = element(Left, T),
22+
C = element(Right, T),
23+
Sum = A + B + C,
24+
case Sum of
25+
0 ->
26+
Triplet = [A, B, C],
27+
NewAcc = [Triplet | Acc],
28+
NewLeft = skip_forward(T, B, Left + 1, Right),
29+
NewRight = skip_backward(T, C, NewLeft, Right - 1),
30+
two_sum(T, I, NewLeft, NewRight, A, NewAcc);
31+
_ when Sum < 0 ->
32+
two_sum(T, I, Left + 1, Right, A, Acc);
33+
_ ->
34+
two_sum(T, I, Left, Right - 1, A, Acc)
35+
end.
36+
skip_forward(T, Val, Pos, Right) when Pos =< Right, element(Pos, T) =:= Val ->
37+
skip_forward(T, Val, Pos + 1, Right);
38+
skip_forward(_T, _Val, Pos, _Right) ->
39+
Pos.
40+
skip_backward(T, Val, Left, Pos) when Pos >= Left, element(Pos, T) =:= Val ->
41+
skip_backward(T, Val, Left, Pos - 1);
42+
skip_backward(_T, _Val, _Left, Pos) ->
43+
Pos.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
defmodule Solution do
2+
@spec three_sum(nums :: [integer]) :: [[integer]]
3+
def three_sum(nums) do
4+
nums = List.to_tuple(Enum.sort(nums))
5+
do_three_sum(nums, 0, tuple_size(nums), [])
6+
end
7+
defp do_three_sum(nums, i, len, acc) do
8+
val_i = elem(nums, i)
9+
cond do
10+
val_i > 0 or i > len - 3 ->
11+
acc
12+
i == 0 or elem(nums, i - 1) != val_i ->
13+
acc = find_triplets(nums, i, i + 1, len - 1, acc)
14+
do_three_sum(nums, i + 1, len, acc)
15+
true ->
16+
do_three_sum(nums, i + 1, len, acc)
17+
end
18+
end
19+
defp find_triplets(_nums, _i, l, r, acc) when l >= r, do: acc
20+
defp find_triplets(nums, i, l, r, acc) do
21+
val_i = elem(nums, i)
22+
val_l = elem(nums, l)
23+
val_r = elem(nums, r)
24+
sum = val_i + val_l + val_r
25+
cond do
26+
sum > 0 ->
27+
find_triplets(nums, i, l, r - 1, acc)
28+
sum < 0 ->
29+
find_triplets(nums, i, l + 1, r, acc)
30+
true ->
31+
acc = [[val_i, val_l, val_r] | acc]
32+
l = grow_from_left(nums, l + 1, r, val_l)
33+
r = shrink_from_right(nums, l, r - 1, val_r)
34+
find_triplets(nums, i, l, r, acc)
35+
end
36+
end
37+
defp shrink_from_right(nums, l, r, prev_val_r) do
38+
cond do
39+
r <= l or elem(nums, r) != prev_val_r -> r
40+
true -> shrink_from_right(nums, l, r - 1, prev_val_r)
41+
end
42+
end
43+
defp grow_from_left(nums, l, r, prev_val_l) do
44+
cond do
45+
l >= r or elem(nums, l) != prev_val_l -> l
46+
true -> grow_from_left(nums, l + 1, r, prev_val_l)
47+
end
48+
end
49+
end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
func threeSum(nums []int) [][]int {
2+
sort.Ints(nums)
3+
res := [][]int{}
4+
for i := 0; i < len(nums)-2; i++ {
5+
if i > 0 && nums[i] == nums[i-1] {
6+
continue
7+
}
8+
l, r := i+1, len(nums)-1
9+
for l < r {
10+
sum := nums[i] + nums[l] + nums[r]
11+
if sum < 0 {
12+
l++
13+
} else if sum > 0 {
14+
r--
15+
} else {
16+
res = append(res, []int{nums[i], nums[l], nums[r]})
17+
for l < r && nums[l] == nums[l+1] {
18+
l++
19+
}
20+
for l < r && nums[r] == nums[r-1] {
21+
r--
22+
}
23+
l++
24+
r--
25+
}
26+
}
27+
}
28+
return res
29+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Solution {
2+
public List<List<Integer>> threeSum(int[] nums) {
3+
List<List<Integer>> res = new ArrayList<>();
4+
Arrays.sort(nums);
5+
for (int i = 0; i < nums.length - 2; ++i) {
6+
if (i > 0 && nums[i] == nums[i - 1]) continue;
7+
int l = i + 1, r = nums.length - 1;
8+
while (l < r) {
9+
int sum = nums[i] + nums[l] + nums[r];
10+
if (sum < 0) l++;
11+
else if (sum > 0) r--;
12+
else {
13+
res.add(Arrays.asList(nums[i], nums[l], nums[r]));
14+
while (l < r && nums[l] == nums[l + 1]) l++;
15+
while (l < r && nums[r] == nums[r - 1]) r--;
16+
l++; r--;
17+
}
18+
}
19+
}
20+
return res;
21+
}
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @param {number[]} nums
3+
* @return {number[][]}
4+
*/
5+
var threeSum = function(nums) {
6+
nums.sort((a, b) => a - b);
7+
const res = [];
8+
for (let i = 0; i < nums.length - 2; i++) {
9+
if (i > 0 && nums[i] === nums[i - 1]) continue;
10+
let l = i + 1, r = nums.length - 1;
11+
while (l < r) {
12+
const sum = nums[i] + nums[l] + nums[r];
13+
if (sum < 0) l++;
14+
else if (sum > 0) r--;
15+
else {
16+
res.push([nums[i], nums[l], nums[r]]);
17+
while (l < r && nums[l] === nums[l + 1]) l++;
18+
while (l < r && nums[r] === nums[r - 1]) r--;
19+
l++; r--;
20+
}
21+
}
22+
}
23+
return res;
24+
};

0 commit comments

Comments
 (0)