Skip to content

Commit 92e54ef

Browse files
authored
Merge pull request #1391 from river20s/main
[river20s] WEEK 05 solutions
2 parents b7de622 + fcf21f7 commit 92e54ef

File tree

4 files changed

+189
-0
lines changed

4 files changed

+189
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Solution(object):
2+
def maxProfit(self, prices):
3+
"""
4+
:type prices: List[int]
5+
:rtype: int
6+
์ฃผ์–ด์ง„ prices๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์ˆœํšŒํ•˜๋ฉด์„œ
7+
์ง€๊ธˆ๊นŒ์ง€์˜ ์ตœ์†Ÿ๊ฐ’์„ ์ถ”์ ํ•˜๊ณ ,
8+
'ํ˜„์žฌ ๊ฐ€๊ฒฉ - ์ง€๊ธˆ๊นŒ์ง€์˜ ์ตœ์†Ÿ๊ฐ’'์œผ๋กœ ๊ณ„์‚ฐ๋˜๋Š” ์ด์ต์ด
9+
'์ง€๊ธˆ๊นŒ์ง€์˜ ์ตœ๋Œ€ ์ด์ต(์ดˆ๊ธฐ 0)๋ณด๋‹ค ํฌ๋ฉด ๊ฐฑ์‹ ํ•˜์—ฌ
10+
์ตœ์ข… ์ตœ๋Œ€ ์ด์ต ๊ตฌํ•˜๊ธฐ ๋ฌธ์ œ
11+
Time Complexity: O(n)
12+
Space Complexity: O(1)
13+
"""
14+
max_profit = 0 # ์ด์ต์ด ์—†์„ ๋•Œ 0์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ์ดˆ๊ธฐํ™”
15+
min_price = float('inf') # ์ตœ์†Œ ๊ฐ€๊ฒฉ ์ €์žฅ, ๋ฌดํ•œ๋Œ€๋กœ ์ดˆ๊ธฐํ™”ํ•ด์„œ ๋ฃจํ”„ ์ฒซ ๋ฒˆ์งธ ๊ฐ€๊ฒฉ๋ถ€ํ„ฐ ์ตœ์†Œ ๊ฐ€๊ฒฉ์— ์ €์žฅ
16+
17+
for price in prices:
18+
# ์ตœ๋Œ€ ์ด์ต ๊ฐฑ์‹ 
19+
max_profit = max(max_profit, (price - min_price))
20+
# ์ตœ์†Œ ๊ฐ€๊ฒฉ ๊ฐฑ์‹ 
21+
min_price = min(min_price, price)
22+
# ์ตœ๋Œ€ ์ด์ต(max_profit) ๊ฐฑ์‹  ์ดํ›„ ์ตœ์†Œ ๊ฐ€๊ฒฉ(min_price) ๊ฐฑ์‹ ํ•ด์•ผ ํ•จ
23+
# ์ตœ๋Œ€ ์ด์ต ์ž์ฒด๋Š” ์ด๋ฏธ '์‚ฐ' ์ฃผ์‹์— ๋Œ€ํ•ด ๊ณ„์‚ฐํ•ด์•ผ ํ•˜๋ฏ€๋กœ
24+
# ์‚ฌ๋Š” ๋™์‹œ ํŒ” ์ˆ˜ ์—†์Œ
25+
26+
return max_profit

โ€Žgroup-anagrams/river20s.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import collections
2+
from typing import List
3+
4+
class Solution(object):
5+
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
6+
"""
7+
:type strs: List[str]
8+
:rtype: List[List[str]]
9+
๊ฐ ๋ฌธ์ž์—ด์„ ์ˆœํšŒํ•˜๋ฉด์„œ ์•ŒํŒŒ๋ฒณ ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ ๊ฒฐ๊ณผ๋ฅผ tuple๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ Key๋กœ ํ•˜๊ณ ,
10+
๊ทธ Key์˜ ์›๋ž˜ ๋ฌธ์ž์—ด์„ Value๋กœ ํ•˜๋Š” ๋”•์…”๋„ˆ๋ฆฌ๋ฅผ ํ†ตํ•ด ์• ๋„ˆ๊ทธ๋žจ์„ ๊ทธ๋ฃนํ™” ํ•˜๋Š” ๋ฌธ์ œ
11+
๋”•์…”๋„ˆ๋ฆฌ์˜ Value๋งŒ ๋ชจ์•„์„œ ๋ฐ˜ํ™˜ํ•จ
12+
Time Complexity: O(N*K log K) (๋‹จ, N์€ ์ž…๋ ฅ ๋ฆฌ์ŠคํŠธ ์•ˆ์˜ ๋ฌธ์ž์—ด ๊ฐœ์ˆ˜(๋ฆฌ์ŠคํŠธ ๊ธธ์ด), K๋Š” ๋ฌธ์ž์—ด ํ•˜๋‚˜ ๋‹น ๊ธธ์ด)
13+
-> ์ •๋ ฌ์— O(K log K)์‹œ๊ฐ„ ์†Œ์š”, ์ •๋ ฌ ์ž‘์—…์€ ๋ฆฌ์ŠคํŠธ ์•ˆ์˜ ๋ฌธ์ž์—ด ๊ฐœ์ˆ˜ N๋งŒํผ ๋ฐ˜๋ณต
14+
Space Complexity: O(N*K)
15+
-> ๋”•์…”๋„ˆ๋ฆฌ๋ฅผ ํ†ตํ•ด ์›๋ณธ ๋ฌธ์ž์—ด N๊ฐœ๊ฐ€ ๋ชจ๋‘ ์ €์žฅ๋จ
16+
"""
17+
# collections์˜ defaultdict ์‚ฌ์šฉํ•˜์—ฌ Key ์—†์„ ๋•Œ ์ž๋™์œผ๋กœ ๋นˆ ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑํ•จ
18+
# Key: ์ •๋ ฌ๋œ ๋ฌธ์ž์—ด, Value: ์›๋ž˜ ๋ฌธ์ž์—ด์˜ ๋ฆฌ์ŠคํŠธ
19+
anagram_groups = collections.defaultdict(list)
20+
21+
# s๋Š” ์ž…๋ ฅ strs์˜ ๊ฐ ๋ฌธ์ž์—ด
22+
# ๋ชจ๋“  s์— ๋Œ€ํ•ด ์ˆœํšŒ
23+
for s in strs:
24+
# s๋ฅผ ์•ŒํŒŒ๋ฒณ ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๊ณ , Key๋กœ ์“ฐ๊ธฐ ์œ„ํ•ด ํŠœํ”Œ๋กœ ๋ณ€ํ™˜ํ•จ
25+
# sorted(s)๋Š” ๊ฐ ๋ฌธ์ž๋ฅผ ์š”์†Œ๋กœ ๊ฐ–๋Š” ๋ฆฌ์ŠคํŠธ(์˜ˆ: ['h', 'i'])
26+
# ํŠœํ”Œ๋กœ ๋ฐ”๊ฟ”์„œ Key๋กœ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์˜€์Œ
27+
key = tuple(sorted(s))
28+
# defaultdict ์‚ฌ์šฉํ•˜๋ฏ€๋กœ, Key ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ ๋ถˆํ•„์š”
29+
# ํ•ด๋‹น Key์˜ Value์— ์›๋ž˜ ๋ฌธ์ž์—ด s ์ถ”๊ฐ€
30+
anagram_groups[key].append(s)
31+
# ๋”•์…”๋„ˆ๋ฆฌ Value๋งŒ ๋ชจ์•„ ๋ฐ˜ํ™˜
32+
return list(anagram_groups.values())
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
class TrieNode:
2+
# ํŠธ๋ผ์ด ๋…ธ๋“œ
3+
def __init__(self):
4+
self.children = {}
5+
# ๋‹จ์–ด์˜ ๋์„ ๋‚˜ํƒ€๋‚ด๊ธฐ ์œ„ํ•œ ํ”Œ๋ž˜๊ทธ
6+
self.isEndOfWord = False
7+
8+
class Trie:
9+
# ํŠธ๋ผ์ด
10+
def __init__(self):
11+
self.root = TrieNode()
12+
13+
def insert(self, word: str) -> None:
14+
# ์‚ฝ์ž… ์—ฐ์‚ฐ
15+
# Time Complexity: O(L) (L์€ word์˜ ๊ธธ์ด)
16+
# Space Complexity: O(M) (M์€ ํŠธ๋ผ์ด์— ์‚ฝ์ž…๋œ ๋ชจ๋“  ๋‹จ์–ด๋“ค์˜ ์ด ๋ฌธ์ž ๊ฐœ์ˆ˜ ํ•ฉ)
17+
currentNode = self.root
18+
19+
for char in word:
20+
if char not in currentNode.children:
21+
currentNode.children[char] = TrieNode()
22+
currentNode = currentNode.children[char]
23+
currentNode.isEndOfWord = True
24+
25+
def search(self, word: str) -> bool:
26+
# ์™„์ „ ๊ฒ€์ƒ‰ ์—ฐ์‚ฐ
27+
# Time Complexity: O(L) (L์€ word์˜ ๊ธธ์ด)
28+
# Space Complexity: O(M)
29+
currentNode = self.root
30+
for char in word:
31+
if char not in currentNode.children:
32+
return False
33+
currentNode = currentNode.children[char]
34+
return currentNode.isEndOfWord
35+
36+
def startsWith(self, prefix: str) -> bool:
37+
# ์ ‘๋‘์‚ฌ ์ผ์น˜ ๊ฒ€์‚ฌ ์—ฐ์‚ฐ
38+
# Time Complexity: O(P) (P๋Š” Prefix์˜ ๊ธธ์ด)
39+
# Space Complexity: O(M)
40+
currentNode = self.root
41+
for char in prefix:
42+
if char not in currentNode.children:
43+
return False
44+
currentNode = currentNode.children[char]
45+
return True
46+
47+
48+
49+
# Your Trie object will be instantiated and called as such:
50+
# obj = Trie()
51+
# obj.insert(word)
52+
# param_2 = obj.search(word)
53+
# param_3 = obj.startsWith(prefix)

โ€Žword-break/river20s.py

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
class TrieNode:
2+
def __init__(self):
3+
self.children = {}
4+
self.isEndOfWord = False
5+
6+
class Trie:
7+
def __init__(self):
8+
self.root = TrieNode()
9+
10+
def insert(self, word: str) -> None:
11+
currentNode = self.root
12+
for char in word:
13+
if char not in currentNode.children:
14+
currentNode.children[char] = TrieNode()
15+
currentNode = currentNode.children[char]
16+
currentNode.isEndOfWord = True
17+
18+
# <-- ์—ฌ๊ธฐ๊นŒ์ง€ Trie ๊ตฌํ˜„์„ ์œ„ํ•œ TrieNode์™€ Trie ํด๋ž˜์Šค
19+
# --> ์—ฌ๊ธฐ๋ถ€ํ„ฐ Word Break ๋ฌธ์ œ ํ‘ธ๋Š” Solution ํด๋ž˜์Šค
20+
21+
class Solution:
22+
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
23+
24+
# 1. ํŠธ๋ผ์ด ๊ตฌ์ถ•
25+
# wordDict ๋ชจ๋“  ๋‹จ์–ด -> ํŠธ๋ผ์ด ๋„ฃ๊ธฐ
26+
trie = Trie()
27+
for word in wordDict:
28+
trie.insert(word)
29+
30+
n = len(s) # ๋ฌธ์ž์—ด s์˜ ๊ธธ์ด, ๋‚˜์ค‘์— ์ธ๋ฑ์Šค ๋๊นŒ์ง€ ๋„๋‹ฌํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•จ
31+
32+
# <<<--- ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ์บ์‹œ ์ดˆ๊ธฐํ™” ---<<<
33+
# key: start_index, value: s[start_index:] ๋ถ„ํ•  ๊ฐ€๋Šฅ ์—ฌ๋ถ€ (True/False)
34+
memo = {}
35+
36+
# 2. ์žฌ๊ท€ ํ•จ์ˆ˜ ์ •์˜
37+
# canBreak(start_index): s[strat_index:] ๋ถ€๋ถ„์„ ๋ถ„ํ• ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธ
38+
def canBreak(start_index: int) -> bool:
39+
40+
# <<<--- ์บ์‹œ ํ™•์ธ ---<<<
41+
# ์ด start_index์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ์ด๋ฏธ memo์— ์žˆ์œผ๋ฉด ๋ฐ”๋กœ ๋ฐ˜ํ™˜
42+
if start_index in memo:
43+
return memo[start_index]
44+
45+
# ๋ฒ ์ด์Šค ์ผ€์ด์Šค
46+
# ์‹œ์ž‘ ์ธ๋ฑ์Šค(start_index)๊ฐ€ ๋ฌธ์ž์—ด ๋์— ๋„๋‹ฌํ–ˆ๋‹ค๋ฉด ์„ฑ๊ณต
47+
if start_index == n:
48+
return True
49+
50+
# ํ˜„์žฌ start_index๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๋‹จ์–ด๋ฅผ ํŠธ๋ผ์ด๋ฅผ ์ด์šฉํ•ด ์ฐพ๊ณ 
51+
# ๊ฐ ๋‹จ์–ด์— ๋Œ€ํ•ด ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์ด ๋ถ„ํ•  ๊ฐ€๋Šฅํ•œ์ง€ ์žฌ๊ท€์ ์œผ๋กœ ํ™•์ธ
52+
currentNode = trie.root
53+
for i in range(start_index, n):
54+
char = s[i]
55+
56+
# ํ˜„์žฌ ๋ฌธ์ž๊ฐ€ ํŠธ๋ผ์ด ๊ฒฝ๋กœ์— ์—†๋‹ค๋ฉด ํ•ด๋‹น ํŠธ๋ผ์ด ํƒ์ƒ‰์€ ๋”์ด์ƒ ์ง„ํ–‰ํ•˜์ง€ ์•Š์Œ
57+
if char not in currentNode.children:
58+
break
59+
60+
# ํŠธ๋ผ์ด์˜ ๋‹ค์Œ ๋…ธ๋“œ๋กœ ์ด๋™
61+
currentNode = currentNode.children[char]
62+
63+
# ์ด๋™ํ•œ ๋…ธ๋“œ๊ฐ€ ๋‹จ์–ด์˜ ๋์ด๋ผ๋ฉด
64+
if currentNode.isEndOfWord:
65+
# ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„ s[i+1:]์— ๋Œ€ํ•ด์„œ๋„ ๋ถ„ํ•  ๊ฐ€๋Šฅํ•œ์ง€ ์žฌ๊ท€ ํ˜ธ์ถœ
66+
if canBreak(i + 1):
67+
# ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„ ๋ถ„ํ•  ์„ฑ๊ณต => ์ „์ฒด ๋ถ„ํ•  ๊ฐ€๋Šฅ
68+
# <<<--- ์„ฑ๊ณต ๊ฒฐ๊ณผ ์บ์‹œ์— ์ €์žฅ ---<<<
69+
memo[start_index] = True
70+
return True
71+
# start_index๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ๋‹จ์–ด ๋ถ„ํ• ์„ ์‹œ๋„ํ–ˆ์œผ๋‚˜
72+
# ์„ฑ๊ณต์ ์ธ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด
73+
# <<<--- ์‹คํŒจ ๊ฒฐ๊ณผ ์บ์‹œ์— ์ €์žฅ ---<<<
74+
memo[start_index] = False
75+
return False
76+
77+
# 3. ์žฌ๊ท€ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ์ž‘
78+
return canBreak(0)

0 commit comments

Comments
ย (0)