Skip to content

Commit 0752d78

Browse files
committed
add combination-sum solution
1 parent 2e06dce commit 0752d78

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

combination-sum/jongwanra.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""
2+
[Problem]
3+
https://leetcode.com/problems/combination-sum/
4+
5+
candidates: unique array of integers
6+
return a list of all unique combinations of candidates == target
7+
any order
8+
9+
하나의 숫자는 candidates에서 무제한으로 선택할 수 있다.
10+
두 조합이 서로 다르다고 간주되는 조건은, 선택된 숫자 중 적어도 하나의 개수가 다를 때이다.
11+
[Brainstorming]
12+
DFS를 이용해서 Combination을 만든다.
13+
종료조건: target == sum || target > sum
14+
15+
[Plan]
16+
1. candidates를 오름차순 정렬
17+
2. DFS
18+
19+
[Complexity]
20+
N -> candidates.length
21+
M -> approximately target divided by the smallest candidate. -> target / min(candidates)
22+
Time: O(N^M)
23+
Space: O(N + M)
24+
- 재귀 호출 스택: 깊이는 최대 target / min(candidates)
25+
- chosen: 재귀 스택 깊이 만큼 공간 차지
26+
- cache: 최악의 경우 answer와 같은 개수의 조합 저장 -> O(number of combinations)
27+
"""
28+
29+
from typing import List
30+
31+
32+
class Solution:
33+
def combinationSum1(self, candidates: List[int], target: int) -> List[List[int]]:
34+
cache = set()
35+
answer = []
36+
chosen = []
37+
38+
def dfs(sum: int) -> None:
39+
nonlocal target, candidates, cache, answer, chosen
40+
print(chosen)
41+
if sum > target:
42+
return
43+
if sum == target:
44+
copied_chosen = chosen[:]
45+
copied_chosen.sort()
46+
47+
cache_key = tuple(copied_chosen)
48+
if cache_key in cache:
49+
# print(f"already exists {cache_key} in cache")
50+
return
51+
cache.add(cache_key)
52+
answer.append(copied_chosen)
53+
54+
for candidate in candidates:
55+
chosen.append(candidate)
56+
dfs(sum + candidate)
57+
chosen.pop()
58+
59+
dfs(0)
60+
return answer
61+
62+
"""
63+
중복 조합 방지 another solution
64+
ref: https://www.algodale.com/problems/combination-sum/
65+
66+
[Complexity]
67+
N -> candidates.length
68+
M -> target / min(candidates)
69+
Time: O(N^M)
70+
Space: O(M)
71+
"""
72+
73+
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
74+
answer = []
75+
combi = []
76+
77+
def dfs(sum: int, start: int) -> None:
78+
nonlocal target, answer, combi, candidates
79+
80+
if sum > target:
81+
return
82+
if sum == target:
83+
answer.append(combi[:])
84+
return
85+
86+
for index in range(start, len(candidates)):
87+
candidate = candidates[index]
88+
combi.append(candidate)
89+
dfs(sum + candidate, index)
90+
combi.pop()
91+
92+
dfs(0, 0)
93+
return answer
94+
95+
96+
sol = Solution()
97+
# print(sol.combinationSum([2,3,6,7], 7))
98+
print(sol.combinationSum([2, 3, 5], 8))
99+
# print(sol.combinationSum([2], 1))
100+

0 commit comments

Comments
 (0)