Skip to content

Commit 320f246

Browse files
authored
Merge pull request #378 from lymchgmk/feat/week3
[EGON] Week 03 Solutions
2 parents 4480634 + c218258 commit 320f246

File tree

3 files changed

+75
-25
lines changed

3 files changed

+75
-25
lines changed

โ€Žcoin-change/EGON.py

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,48 @@
11
from typing import List
22
from unittest import TestCase, main
3-
from collections import defaultdict
43

54

65
class Solution:
76
def coinChange(self, coins: List[int], amount: int) -> int:
8-
return self.solve_with_dp(coins, amount)
7+
return self.solveWithDP(coins, amount)
98

109
# Unbounded Knapsack Problem
11-
def solve_with_dp(self, coins: List[int], amount: int) -> int:
10+
"""
11+
Runtime: 801 ms (Beats 48.54%)
12+
Time Complexity: O(n)
13+
- coins ๊ธธ์ด๋ฅผ c, amount์˜ ํฌ๊ธฐ๋ฅผ a๋ผ๊ณ  ํ•˜๋ฉด
14+
- coins๋ฅผ ์ •๋ ฌํ•˜๋Š”๋ฐ O(log c)
15+
- dp ๋ฐฐ์—ด ์กฐํšŒ์— O((n + 1) * c)
16+
> c์˜ ์ตœ๋Œ€ ํฌ๊ธฐ๋Š” 12๋ผ์„œ ๋ฌด์‹œ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ O((n + 1) * c) ~= O(n * c) ~= O(n)
17+
18+
Memory: 16.94 MB (Beats 50.74%)
19+
Space Complexity: O(n)
20+
> ํฌ๊ธฐ๊ฐ€ n + 1์ธ dp๋ฅผ ์„ ์–ธํ•˜์—ฌ ์‚ฌ์šฉํ–ˆ์œผ๋ฏ€๋กœ O(n + 1) ~= O(n)
21+
"""
22+
def solveWithDP(self, coins: List[int], amount: int) -> int:
1223
if amount == 0:
1324
return 0
1425

1526
coins.sort()
1627

1728
if amount < coins[0]:
1829
return -1
30+
31+
dp = [float('inf')] * (amount + 1)
1932

20-
dp = [[0] * (amount + 1) for _ in range(len(coins) + 1)]
21-
for curr_r in range(1, len(coins) + 1):
22-
coin_index = curr_r - 1
23-
curr_coin = coins[coin_index]
24-
if amount < curr_coin:
25-
continue
33+
for coin in coins:
34+
if coin <= amount:
35+
dp[coin] = 1
2636

27-
dp[curr_r][curr_coin] += 1
28-
for curr_amount in range(curr_coin + 1, amount + 1):
29-
for coin in coins:
30-
if 0 < dp[curr_r][curr_amount - coin]:
31-
dp[curr_r][curr_amount] = max(dp[curr_r - 1][curr_amount], dp[curr_r][curr_amount - coin] + 1)
32-
else:
33-
dp[curr_r][curr_amount] = dp[curr_r - 1][curr_amount]
37+
for curr_amount in range(amount + 1):
38+
for coin in coins:
39+
if 0 <= curr_amount - coin:
40+
dp[curr_amount] = min(
41+
dp[curr_amount],
42+
dp[curr_amount - coin] + 1
43+
)
3444

35-
return dp[-1][-1] if 0 < dp[-1][-1] else -1
45+
return dp[-1] if dp[-1] != float('inf') else -1
3646

3747

3848
class _LeetCodeTestCases(TestCase):
@@ -57,7 +67,7 @@ def test_3(self):
5767
def test_4(self):
5868
coins = [1, 2147483647]
5969
amount = 2
60-
output = -1
70+
output = 2
6171
self.assertEqual(Solution.coinChange(Solution(), coins, amount), output)
6272

6373

โ€Žcombination-sum/EGON.py

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,23 @@
55

66
class Solution:
77
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
8-
return self.solve_with_dfs(candidates, target)
8+
return self.solveWithBackTracking(candidates, target)
99

1010
"""
1111
Runtime: 2039 ms (Beats 5.01%)
12-
Time Complexity: ?
13-
12+
Time Complexity: O(c * c * log c)
13+
- ์ฒ˜์Œ stack์˜ ํฌ๊ธฐ๋Š” c์— ๋น„๋ก€ O(c)
14+
- ์ค‘๋ณต ์ œ๊ฑฐ์— ์‚ฌ์šฉํ•˜๋Š” ๋ณ€์ˆ˜์ธ curr_visited_checker ์ƒ์„ฑ์— O(c' log c')
15+
- stack์˜ ๋‚ด๋ถ€ ๋กœ์ง์—์„œ c์— ๋น„๋ก€ํ•œ for๋ฌธ์„ ์ˆœํšŒํ•˜๋Š”๋ฐ O(c)
16+
> O(c) * O(c' log c') + O(c) * O(c) ~= O(c * c * log c)
17+
1418
Memory: 16.81 MB (Beats 11.09%)
15-
Space Complexity: ?
19+
Space Complexity: O(c * c)
20+
- curr_combination์˜ ํฌ๊ธฐ๊ฐ€ c์— ๋น„๋ก€
21+
- stack์˜ ํฌ๊ธฐ๋Š” curr_combination์˜ ํฌ๊ธฐ์™€ c์— ๋น„๋ก€
22+
> O(c * c)
1623
"""
17-
def solve_with_dfs(self, candidates: List[int], target: int) -> List[List[int]]:
24+
def solveWithDFS(self, candidates: List[int], target: int) -> List[List[int]]:
1825
result = []
1926
stack = []
2027
visited = defaultdict(bool)
@@ -38,6 +45,38 @@ def solve_with_dfs(self, candidates: List[int], target: int) -> List[List[int]]:
3845

3946
return result
4047

48+
"""
49+
Runtime: 58 ms (Beats 32.30%)
50+
Time Complexity: O(c * c)
51+
- candidates ์ •๋ ฌ์— O(log c)
52+
- ์ฒซ depte์—์„œ dfs ํ•จ์ˆ˜ ํ˜ธ์ถœ์— O(c)
53+
- ๊ทธ ํ›„ candidates์˜ ๊ธธ์ด์— ๋น„๋ก€ํ•ด์„œ ์žฌ๊ท€์ ์œผ๋กœ dfs๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ O(c)
54+
- lower_bound_idx์— ๋”ฐ๋ผ range๊ฐ€ ๊ฐ์†Œํ•˜๊ธฐ๋Š” ํ•˜๋‚˜ ์ผ๋‹จ์€ ๋น„๋ก€ O(c')
55+
> O(log c) + O(c * c') ~= O(c * c), ๋‹จ c' <= c ์ด๋ฏ€๋กœ ์ด ๋ณต์žก๋„๋Š” upper bound
56+
Memory: 16.59 MB (Beats 75.00%)
57+
Space Complexity: O(c)
58+
- result๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋ชจ๋‘ nonlocal ๋ณ€์ˆ˜๋ฅผ call by reference๋กœ ์ฐธ์กฐ
59+
- dfs ํ•จ์ˆ˜ ํ˜ธ์ถœ๋งˆ๋‹ค ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ฆ๊ฐ€ํ•˜๋Š”๋ฐ, ํ˜ธ์ถœํšŸ์ˆ˜๋Š” candidates์˜ ๊ธธ์ด์— ๋น„๋ก€ O(c)
60+
- lower_bound_idx์— ๋”ฐ๋ผ range๊ฐ€ ๊ฐ์†Œํ•˜๊ธฐ๋Š” ํ•˜๋‚˜ ์ผ๋‹จ์€ ๋น„๋ก€
61+
> O(c), ๋‹จ ์ด ๋ณต์žก๋„๋Š” upper bound
62+
"""
63+
def solveWithBackTracking(self, candidates: List[int], target: int) -> List[List[int]]:
64+
def dfs(stack: List[int], sum: int, lower_bound_idx: int):
65+
nonlocal result, candidates, target
66+
67+
if target < sum:
68+
return
69+
elif sum < target:
70+
for idx in range(lower_bound_idx, len(candidates)):
71+
dfs(stack + [candidates[idx]], sum + candidates[idx], idx)
72+
else: # target == sum
73+
result.append(stack)
74+
return
75+
76+
result = []
77+
candidates.sort()
78+
dfs([], 0, 0)
79+
return result
4180

4281
class _LeetCodeTestCases(TestCase):
4382
def test_1(self):

โ€Žtwo-sum/EGON.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ def twoSum(self, nums: List[int], target: int) -> List[int]:
1010
"""
1111
Runtime: 3762 ms (Beats 5.00%)
1212
Time Complexity: O(n ** 2)
13-
- ํฌ๊ธฐ๊ฐ€ n์ธ nums ๋ฐฐ์—ด์„ 2์ค‘์œผ๋กœ ์กฐํšŒํ•˜๋ฏ€๋กœ O(n ** 2)
13+
> ํฌ๊ธฐ๊ฐ€ n์ธ nums ๋ฐฐ์—ด์„ 2์ค‘์œผ๋กœ ์กฐํšŒํ•˜๋ฏ€๋กœ O(n ** 2)
1414
1515
Memory: 17.42 MB (Beats 61.58%)
16-
Space Complexity: ?
16+
Space Complexity: O(1)
17+
> ๋”ฑํžˆ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜ ์—†์Œ (๋ฐ˜ํ™˜ํ•˜๋Š” list ์ œ์™ธ)
1718
"""
1819
def solveWithBruteForce(self, nums: List[int], target: int) -> List[int]:
1920
for i in range(len(nums)):

0 commit comments

Comments
ย (0)