Skip to content

Commit ae1880b

Browse files
committed
3Sum solution
1 parent 92777cc commit ae1880b

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

3sum/clara-shin.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* 배열에서 합이 0이 되는 세 숫자를 찾기
3+
*
4+
* 요구사항 & 제약조건:
5+
* 세 개의 다른 인덱스에 있는 숫자들의 합이 0이 되어야 함
6+
* 결과에 중복된 조합이 없어야 함
7+
* 배열 크기는 3에서 3000까지
8+
* 배열 요소는 -10^5부터 10^5까지의 정수
9+
*
10+
* 접근방법:
11+
* 1. 브루트포스(이중for문, 완전탐색) - O(n^3) 시간복잡도
12+
* 2. 정렬 후 투 포인터 - O(n^2) 시간복잡도 ✅
13+
*
14+
* 배열을 정렬 후, 배열을 순회하며 각 요소를 첫 번째 숫자로 고정
15+
* 고정된 숫자 다음부터 ~ 배열 끝까지 투 포인터를 사용 ➡️ 나머지 두 수의 합이 첫 번째 수의 음수가 되는 조합 찾기
16+
* 중복을 피하기 위해 같은 값을 가진 연속된 요소는 스킵
17+
*/
18+
19+
/**
20+
* @param {number[]} nums
21+
* @return {number[][]}
22+
*/
23+
var threeSum = function (nums) {
24+
const result = [];
25+
const n = nums.length;
26+
27+
if (n < 3) return result;
28+
29+
nums.sort((a, b) => a - b); // 오름차순 정렬
30+
31+
if (nums[0] > 0 || nums[n - 1] < 0) return result;
32+
33+
// 배열을 순회하며 첫 번째 숫자 고정
34+
for (let i = 0; i < n - 2; i++) {
35+
// 중복된 값 건너뛰기 (첫 번째 숫자)
36+
if (i > 0 && nums[i] === nums[i - 1]) continue;
37+
38+
// 첫 번째 숫자가 양수면 for문 탈출
39+
if (nums[i] > 0) break;
40+
41+
// 현재 숫자와 가장 작은 두 숫자의 합 > 0 => 탈출
42+
if (nums[i] + nums[i + 1] + nums[i + 2] > 0) break;
43+
44+
// 현재 숫자와 가장 큰 두 숫자의 합 < 0 => 건너뛰기
45+
if (nums[i] + nums[n - 2] + nums[n - 1] < 0) continue;
46+
47+
// 두 번째, 세 번째 숫자를 찾기 위한 투 포인터
48+
let left = i + 1;
49+
let right = n - 1;
50+
51+
while (left < right) {
52+
const sum = nums[i] + nums[left] + nums[right];
53+
54+
if (sum < 0) {
55+
// 합이 0보다 작으면 left 포인터를 오른쪽으로 이동
56+
left++;
57+
} else if (sum > 0) {
58+
// 합이 0보다 크면 right 포인터를 왼쪽으로 이동
59+
right--;
60+
} else {
61+
// 합이 0이면 결과에 추가
62+
result.push([nums[i], nums[left], nums[right]]);
63+
64+
// 중복된 값 건너뛰기 (두 번째, 세 번째 숫자)
65+
while (left < right && nums[left] === nums[left + 1]) left++;
66+
while (left < right && nums[right] === nums[right - 1]) right--;
67+
68+
// 다음 조합을 찾기 위해 포인터 이동
69+
left++;
70+
right--;
71+
}
72+
}
73+
}
74+
75+
return result;
76+
};

0 commit comments

Comments
 (0)