Skip to content

Commit f02818b

Browse files
committed
solve(w02): 15. 3Sum
1 parent 9412d3c commit f02818b

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

3sum/seungriyou.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# https://leetcode.com/problems/3sum/
2+
3+
from typing import List
4+
5+
6+
class Solution:
7+
def threeSum_slower(self, nums: List[int]) -> List[List[int]]:
8+
"""
9+
[Complexity]
10+
- TC: O(n^2)
11+
- SC: O(n)
12+
13+
[Approach]
14+
two sum 문제에서 고정된 하나의 값만 추가해서 풀 수 있다.
15+
정렬을 한 차례하면, duplicated triplet 처리가 가능하다.
16+
"""
17+
18+
n = len(nums)
19+
nums.sort()
20+
21+
def two_sum(fixed_idx):
22+
remains = {}
23+
fixed_val = nums[fixed_idx]
24+
res = set()
25+
26+
for i in range(fixed_idx + 1, n):
27+
num = nums[i]
28+
if num in remains:
29+
res.add((nums[fixed_idx], nums[remains[num]], nums[i]))
30+
remains[-fixed_val - nums[i]] = i
31+
32+
return res
33+
34+
res = set()
35+
for i in range(n - 2):
36+
if ts := two_sum(i):
37+
res |= set(ts)
38+
39+
return [list(r) for r in res]
40+
41+
def threeSum(self, nums: List[int]) -> List[List[int]]:
42+
"""
43+
[Complexity]
44+
- TC: O(n^2)
45+
- SC: O(1) (res 제외한 extra space)
46+
47+
[Approach]
48+
정렬 후, 하나의 값을 고정해두고 two pointer를 사용하는 방식을 적용할 수 있다.
49+
이때 매 turn에서 중복 원소를 고려해서 미리 이동하면 duplicated triplet을 방지할 수 있다.
50+
"""
51+
52+
n = len(nums)
53+
res = []
54+
55+
# nums 오름차순 정렬
56+
nums.sort()
57+
58+
for i in range(n - 2): # -- 하나의 값 고정
59+
# 고정한 값이 이전에 나왔던 값이면 빠르게 넘어가기
60+
if i > 0 and nums[i] == nums[i - 1]:
61+
continue
62+
63+
# 고정된 값보다 큰 값 범위에서, 양 끝에서부터 좁혀오며 확인
64+
j, k = i + 1, n - 1
65+
while j < k:
66+
_sum = nums[i] + nums[j] + nums[k]
67+
68+
# (1) _sum이 0보다 크면 k를 왼쪽으로 한 칸 이동
69+
if _sum > 0:
70+
k -= 1
71+
# (2) _sum이 0보다 작으면 j를 오른쪽으로 한 칸 이동
72+
elif _sum < 0:
73+
j += 1
74+
# (3) _sum이 0이라면 res에 추가
75+
else:
76+
triplet = [nums[i], nums[j], nums[k]]
77+
res.append(triplet)
78+
79+
# 중복 원소 건너뛰기 (j는 오른쪽으로, k는 왼쪽으로)
80+
while j < k and nums[j] == triplet[1]:
81+
j += 1
82+
while j < k and nums[k] == triplet[2]:
83+
k -= 1
84+
85+
return res

0 commit comments

Comments
 (0)