-
Notifications
You must be signed in to change notification settings - Fork 125
/
Copy pathhaklee.py
114 lines (93 loc) Β· 5.37 KB
/
haklee.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
"""TC: O(m^n), SC: O(m^n)
candidatesμ μλ κ°μ κ°μ: m
targetμ ν¬κΈ°: n
μμ΄λμ΄:
candidates(μ΄ν cands)μ μλ μ«μλ€μ λν΄μ kλ₯Ό λ§λλ λ°©λ²μ f(k)λΌκ³ νμ.
f(k)λ λ€μμ κ²½μ°λ€μ μ’
ν©ν κ²μ΄λ€.
- candsμ μλ c1μ λ§μ§λ§μΌλ‘ λν΄μ kλ₯Ό λ§λ€μλ€. μ¦, f(k-c1)μ μλ λͺ¨λ λ°©λ²μ λμ c1μ λν¨.
- candsμ μλ c2λ₯Ό λ§μ§λ§μΌλ‘ λν΄μ kλ₯Ό λ§λ€μλ€. μ¦, f(k-c2)μ μλ λͺ¨λ λ°©λ²μ λμ c2μ λν¨.
...
- candsμ μλ cmμ λ§μ§λ§μΌλ‘ λν΄μ kλ₯Ό λ§λ€μλ€. μ¦, f(k-cm)μ μλ λͺ¨λ λ°©λ²μ λμ cmμ λν¨.
μ΄λ κ² νλ©΄ λ¬Έμ λ, νλμ κ°μ λ§λλ λ°μ μ€λ³΅λ κ²½μ°κ° λμ¬ μ μλ€λ κ²μ΄λ€.
e.g.) candidates = [2, 3], target = 5
f(2) = [[2]]
f(3) = [[3]]
μμ κ°μ νμ©ν΄μ f(5)λ₯Ό ꡬνλ©΄
f(5) = [f(2)μ λ°©λ²λ€μ λμ 3μ λΆμ] + [f(3)μ λ°©λ²λ€μ λμ 2λ₯Ό λΆμ]
= [[2, 3]] + [[3, 2]]
= [[2, 3], [3, 2]]
κ·Έλμ λ§μ§λ§μ κ°μ μμ΄ν
μΌλ‘ μ΄λ£¨μ΄μ§ 리μ€νΈλ₯Ό μ°Ύμμ μ€λ³΅μ μ κ±°ν΄μ€λ€.
μ΄λ² λ¬Έμ μμλ [2, 2, 3], [2, 3, 2], [3, 2, 2] κ°μ΄ λ€μ΄κ°λ μμ΄ν
μ μμλ§ λ€λ₯Έ κ²½μ°λ₯Ό κ°μ κ²μΌλ‘
보μκΈ° λλ¬Έμ λ§μ§λ§μ μ€λ³΅μ μ κ±°νμ§λ§, λ§μ½ μ΄λ€μ μλ‘ λ€λ₯Έ λ°©λ²μΌλ‘ 보λ λ¬Έμ κ° μ£Όμ΄μ§λ€λ©΄ μμ
κ²°κ³Όλ₯Ό κ·Έλλ‘ λ¦¬ν΄νλ©΄ λλ€.
SC:
- λ¬Έμ νΉμ±μ f(i)μ λ€μ΄κ° μ μλ λ°©λ²μ μλ
- iλ₯Ό λ§λλ λ°©λ²μ κΈΈμ΄λ O(i).
- candsμ 1μ΄ μκ³ μ΄ 1λ‘ κ°λ μ±μ΄ λ°©λ² [1, 1, ..., 1]μ μκ°νλ©΄ νΈνλ€.
- candsμ μ΅μκ°μ΄ μ΄λ€ μμ xλΌκ³ ν΄λ [x, x, ..., x]μλ i/xκ° λ€μ΄κ°λλ°, O(i/x)λ O(i).
- κ° λ°©λ²μ λ€μ΄μλ μμ΄ν
μ mκ°μ§ κ²½μ°μ μκ° κ°λ₯. [(c1, c2, ..., cm μ€ νλ), ..., (c1, c2, ..., cm μ€ νλ)]
- μ¦, f(i)μλ O(m^i)κ°μ§ κ²½μ°κ° λ€μ΄κ° μ μλ€.
- f(1), f(2), ..., f(n)μ λ€ λνλ©΄ O(m^1) + O(m^2) + ... + O(m^n) = O(m^n)μ΄ λλ€.
- μ¦, O(m^n).
TC:
- μμ SCμ κ°μ λ°©μμΌλ‘ μ κ·Όμ΄ κ°λ₯νλ€. O(m^n).
"""
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
dp = [[] for _ in range(target + 1)] # μ΄κΈ°ν.
dp[0] = [[]] # 0μ λ§λλ λ°©λ²μ μ무 μ«μλ λ£μ§ μλ κ² ν κ°μ§ λ°©λ²μ΄ μλ€.
for cur in range(1, target + 1): # f(i)λ₯Ό 1λΆν° κ³μ°ν΄λκ°λ©΄μ μ±μ°κΈ° μμ.
for cand in candidates:
prev = cur - cand
if prev >= 0:
dp[cur] += [combi + [cand] for combi in dp[prev]]
# λ§μ§λ§μ μ€λ³΅λ κ²½μ°λ₯Ό μ κ±°ν΄μ€λ€.
return list(set([tuple(sorted(i)) for i in dp[target]]))
"""
μμ΄λμ΄:
μ€κ°μ€κ° κ³μ°νλ©΄μ μ€λ³΅λ κ°μ μ κ±°νλ©΄μ f(i)κ°μ κ΄λ¦¬νλ μμΌλ‘ 컀ν
νλ κ²μ΄ κ°λ₯νλ€.
κ° λ°©λ²μ [c1, ...c1, c2, ..., c2, ... , cm, ..., m] κΌ΄μ΄ λλλ°,
[ ^ ^ ... ^ ]
κ° f(i)λ§λ€ μμ `^` νμλ₯Ό ν΄λ κ³³μ μ°Ύλ λ°©λ²μ μλ§νΌ 곡κ°μ΄ νμνλ€.
μ΄ μ«μλ λλ΅ (i choose m-1)μ΄λΌκ³ μκ°ν μ μλ€.
κ·Έλ¬λ―λ‘ SCμ TC λͺ¨λ O(n choose m) = O((n/m)^m)...?
(ref: https://en.wikipedia.org/wiki/Binomial_coefficient#Bounds_and_asymptotic_formulas)
"""
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
dp = [[] for _ in range(target + 1)]
dp[0] = [[]]
for cur in range(1, target + 1):
for cand in candidates:
prev = cur - cand
if prev >= 0:
dp[cur] += [combi + [cand] for combi in dp[prev]]
dp[cur] = list(set([tuple(sorted(i)) for i in dp[cur]]))
return list(set([tuple(sorted(i)) for i in dp[target]]))
"""
μμ΄λμ΄:
λ§λ€κ³ λμ μ€λ³΅λ κ²½μ°λ₯Ό μ κ±°νμ§ λ§κ³ , μ²μλΆν° μ€λ³΅λ κ²°κ³Όλ₯Ό λ§λ€μ§ μλ κ²λ λ°©λ²μ΄λ€.
κ° λ°©λ²λ§λ€ ν΄λΉ λ°©λ²μμ μ¬μ©ν μ΅λ candidate μΈλ±μ€λ₯Ό λ¬μλκ³ , μ΄ν ν΄λ₯Ό ꡬν λλ ν΄λΉ
μΈλ±μ€ μ΄μμ candidateλ§ μΆκ°ν μ μλλ‘ λ¨μλ₯Ό λ¬μλλ λ°©μμΌλ‘ ꡬν κ°λ₯νλ€.
e.g.) candidate = [2, 5, 3]
f(10)μ λ€μ΄μμ μ μλ λ°©λ²μ
- ([2, 2, 2, 2, 2], 0) : λ§μ§λ§ μμ΄ν
μ΄νμ 2, 5, 3 μ λΆ λ±μ₯ κ°λ₯.
- ([5, 5], 1) : λ§μ§λ§ μμ΄ν
μ΄νμ 5, 3λ§ λ±μ₯ κ°λ₯.
- ([2, 5, 3], 2) : λ§μ§λ§ μμ΄ν
μ΄νμ 3λ§ λ±μ₯ κ°λ₯.
- ([2, 2, 3, 3], 2) : λ§μ§λ§ μμ΄ν
μ΄νμ 3λ§ λ±μ₯ κ°λ₯.
SCμ TCλ λ°λ‘ μμμ O(n choose m)μ κ³μ°ν κ²κ³Ό κ°μ κ²μΌλ‘ 보μΈλ€.
"""
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
dp = [[] for _ in range(target + 1)]
dp[0] = [([], 0)] # (λ°©λ², μ¬μ© κ°λ₯ν candidate index μ΅μκ°) μ.
for cur in range(1, target + 1):
for i in range(len(candidates)):
prev = cur - candidates[i]
if prev >= 0:
dp[cur] += [
(combi[0] + [candidates[i]], i)
for combi in dp[prev]
if i >= combi[1]
]
return [i[0] for i in dp[target]] # λ°©λ²λ§ μΆμΆν΄μ 리ν΄νλ€.