Skip to content

Commit f6b0c1f

Browse files
committedJan 6, 2025·
feat: implement threeSum algorithm
- Finds triplets in unsorted array that add up to 0.
1 parent 23d24fe commit f6b0c1f

File tree

5 files changed

+778
-243
lines changed

5 files changed

+778
-243
lines changed
 

‎.vscode/launch.json

+36-5
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,44 @@
55
"type": "node",
66
"request": "launch",
77
"name": "Vitest Current File",
8-
"program": "${workspaceFolder}/node_modules/.bin/vitest",
9-
"args": ["${fileBasenameNoExtension}", "--config", "vite.config.ts"],
8+
"runtimeExecutable": "pnpm",
9+
"runtimeArgs": [
10+
"exec",
11+
"vitest",
12+
"${fileBasenameNoExtension}",
13+
"--config",
14+
"vite.config.mts"
15+
],
16+
"console": "integratedTerminal",
17+
"internalConsoleOptions": "neverOpen"
18+
},
19+
{
20+
"type": "node",
21+
"request": "launch",
22+
"name": "Debug TypeScript Current File",
23+
"runtimeArgs": ["-r", "tsx"],
24+
"args": ["${relativeFile}"],
25+
"cwd": "${workspaceRoot}",
26+
"console": "integratedTerminal",
27+
"internalConsoleOptions": "neverOpen"
28+
},
29+
{
30+
"type": "node",
31+
"request": "launch",
32+
"name": "Debug TypeScript with pnpm",
33+
"runtimeExecutable": "pnpm",
34+
"runtimeArgs": ["run", "debug"],
1035
"console": "integratedTerminal",
1136
"internalConsoleOptions": "neverOpen",
12-
"windows": {
13-
"program": "${workspaceFolder}/node_modules/jest/bin/jest"
14-
}
37+
"skipFiles": ["<node_internals>/**"]
38+
},
39+
{
40+
"type": "node",
41+
"request": "attach",
42+
"name": "Attach to Process",
43+
"port": 9229,
44+
"restart": true,
45+
"skipFiles": ["<node_internals>/**"]
1546
}
1647
]
1748
}

‎package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
"scripts": {
1010
"build-ts": "tsc",
1111
"build-dev": "tsc --watch",
12-
"start": "nodemon dist/index.js",
12+
"start": "ts-node src/index.ts",
1313
"dev": "concurrently \"pnpm:build-dev\" \"pnpm:start\"",
14+
"debug": "node --inspect-brk -r ts-node/register src/index.ts",
1415
"test:ci": "vitest run",
1516
"test:watch": "vitest watch --ui",
1617
"test:coverage": "vitest run --coverage",
@@ -42,6 +43,8 @@
4243
"lint-staged": "^15.3.0",
4344
"nodemon": "^3.0.1",
4445
"prettier": "^3.0.3",
46+
"ts-node": "^10.9.2",
47+
"tsx": "^4.19.2",
4548
"typescript": "^5.2.2",
4649
"vite-tsconfig-paths": "^5.1.4",
4750
"vitest": "^2.1.8",

‎pnpm-lock.yaml

+653-237
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { threeSum } from '../three-sum';
2+
3+
describe('ThreeSum', () => {
4+
test('should return empty array when input array is empty', () => {
5+
expect(threeSum([])).toEqual([]);
6+
});
7+
8+
test('should return empty array when no triplets sum to zero', () => {
9+
expect(threeSum([1, 2, 3, 4, 5])).toEqual([]);
10+
});
11+
12+
test('should find single triplet that sums to zero', () => {
13+
expect(threeSum([-1, 0, 1])).toEqual([[-1, 0, 1]]);
14+
});
15+
16+
test('should find multiple triplets that sum to zero', () => {
17+
const nums = [-1, 0, 1, 2, -1, -4];
18+
const result = threeSum(nums);
19+
20+
// Each triplet should be sorted internally
21+
const expected = [
22+
[-1, 0, 1], // First solution
23+
[-1, -1, 2], // Second solution
24+
];
25+
26+
// Verify solutions exist
27+
expected.forEach(triplet => {
28+
expect(result).toContainEqual(triplet);
29+
});
30+
31+
// Verify count matches
32+
expect(result.length).toBe(expected.length);
33+
});
34+
35+
test('should handle duplicate numbers correctly', () => {
36+
const result = threeSum([-2, 0, 0, 2, 2]);
37+
expect(result).toEqual([[-2, 0, 2]]);
38+
});
39+
40+
test('should handle all negative numbers', () => {
41+
expect(threeSum([-1, -2, -3, -4])).toEqual([]);
42+
});
43+
44+
test('should handle array with all zeros', () => {
45+
expect(threeSum([0, 0, 0])).toEqual([[0, 0, 0]]);
46+
});
47+
});

‎src/algorithms/three-sum/three-sum.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
export const threeSum = (nums: number[]) => {
2+
nums.sort((a, b) => a - b); // Sort the array
3+
const triplets = [];
4+
5+
for (let i = 0; i < nums.length - 2; i++) {
6+
// Skip the duplicate elements for the first number
7+
if (i > 0 && nums[i] === nums[i - 1]) continue;
8+
9+
let left = i + 1;
10+
let right = nums.length - 1;
11+
12+
while (left < right) {
13+
const sum = nums[i] + nums[left] + nums[right];
14+
15+
if (sum === 0) {
16+
triplets.push([nums[i], nums[left], nums[right]]);
17+
18+
// Skip the duplicate elements for the second and third numbers
19+
while (left < right && nums[left] === nums[left + 1]) left++;
20+
while (left < right && nums[right] === nums[right - 1]) right--;
21+
22+
left++;
23+
right--;
24+
} else if (sum < 0) {
25+
left++;
26+
} else {
27+
right--;
28+
}
29+
}
30+
}
31+
32+
return triplets;
33+
};
34+
35+
const nums = [-3, 0, 1, 2, -1, 1, -2];
36+
const triplets = threeSum(nums);
37+
38+
console.log(triplets);

0 commit comments

Comments
 (0)
Please sign in to comment.