Skip to content

Commit 856bcbe

Browse files
committed
Add #0015 3Sum problem and tests
1 parent 17d9ffa commit 856bcbe

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

difficulty/medium/0015 3Sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../problems/0015-3sum

list/Blind Curated 75/05. 3Sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../problems/0015-3sum

problems/0015-3sum/3sum.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import threeSum from './3sum';
2+
3+
test.each`
4+
nums | expected
5+
${[-1, 0, 1, 2, -1, -4]} | ${[[-1, -1, 2], [-1, 0, 1]]} }
6+
${[]} | ${[]}
7+
${[0]} | ${[]}
8+
${[1, -1]} | ${[]}
9+
`('3Sum: ($nums)', ({ nums, expected }) =>
10+
expect(threeSum(nums)).toEqual(expected)
11+
);

problems/0015-3sum/3sum.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* 簡單想法:
3+
*
4+
* 1. 總和為 0 一定是:
5+
* - 0 + 0 + 0
6+
* - +N + -X + -Y (其中 N = X + Y,並且 X 與 Y 中必定有一項 <= N/2)
7+
* - -N + +X + +Y (其中 N = X + Y,並且 X 與 Y 中必定有一項 <= N/2)
8+
*/
9+
function threeSum(nums: number[]): number[][] {
10+
/** 各數字出現量 */
11+
const counts = nums.reduce(
12+
(all, val) => Object.assign(all, {
13+
[val]: (all[val] ?? 0) + 1,
14+
}), {}
15+
);
16+
17+
const numbers = Object.keys(counts).map(n => parseInt(n, 10));
18+
const postives = numbers.filter(n => n > 0);
19+
const negatives = numbers.filter(n => n < 0);
20+
21+
const matched = postives.reduce(
22+
(all: number[][], pos: number) => negatives
23+
.filter(neg => pos + 2 * neg <= 0 && pos + neg >= 0) // 這邊接受 -N 0 N 的 case
24+
.map(neg => [neg, -pos - neg, pos])
25+
.filter(([a, b, c]) => a === b ? counts[b] >= 2 : counts[b] >= 1)
26+
.concat(all),
27+
counts[0] >= 3
28+
? [[0, 0, 0]]
29+
: []
30+
);
31+
32+
return negatives.reduce(
33+
(all: number[][], neg: number) => postives
34+
.filter(pos => pos * 2 + neg >= 0 && pos + neg < 0) // 這邊不收 N 0 -N 的 case
35+
.map(pos => [neg, -pos - neg, pos])
36+
.filter(([a, b, c]) => b === c ? counts[b] >= 2 : counts[b] >= 1)
37+
.concat(all),
38+
matched,
39+
);
40+
}
41+
42+
export default threeSum

0 commit comments

Comments
 (0)