Skip to content

Commit ca2d7b9

Browse files
authored
chore: merge pull request #1844 from hyogshin/main
[hyogshin] WEEK 5 solutions
2 parents fb39de8 + 2c09eef commit ca2d7b9

File tree

5 files changed

+207
-0
lines changed

5 files changed

+207
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'''
2+
문제 풀이
3+
- 이중 for 문으로 구현시 O(n^2) 으로 시간 초과
4+
- least_num에 현재 날짜 이전에 가장 싸게 살 수 있는 금액을 업데이트
5+
- dp로 해당 날짜까지 가장 큰 수익을 저장
6+
시간 복잡도: O(n)
7+
- for 문 하나 -> O(n)
8+
공간 복잡도: O(1)
9+
- 상수 변수만 사용 -> O(1)
10+
'''
11+
12+
class Solution:
13+
def maxProfit(self, prices: List[int]) -> int:
14+
largest = 0
15+
least = prices[0]
16+
for i in range(len(prices)):
17+
least = min(prices[i], least)
18+
largest = max(prices[i] - least, largest)
19+
return largest
20+
21+
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""
2+
풀이 방법
3+
- 암호화 시 (단어의 개수) + '#' + (단어) 형식 사용
4+
5+
시간 복잡도: O(n)
6+
- encode: join 이 모든 문자열을 이어붙임 -> O(n)
7+
- decode: while 문 -> O(n)
8+
9+
공간 복잡도: O(n)
10+
- encode: 새로운 문자열 생성 -> O(n)
11+
- decode: ans 리스트 -> O(n)
12+
"""
13+
14+
from typing import List
15+
class Solution:
16+
"""
17+
@param: strs: a list of strings
18+
@return: encodes a list of strings to a single string.
19+
"""
20+
def encode(self, strs):
21+
return ''.join(f'{len(s)}#{s}' for s in strs)
22+
23+
"""
24+
@param: str: A string
25+
@return: decodes a single string to a list of strings
26+
"""
27+
def decode(self, s):
28+
29+
ans = []
30+
i = 0
31+
while i < len(s):
32+
j = i
33+
while s[j] != '#':
34+
j += 1
35+
length = int(s[i:j])
36+
start = j + 1
37+
end = start + length
38+
ans.append(s[start:end])
39+
40+
i = end
41+
return ans
42+
43+
if __name__ == "__main__":
44+
sol = Solution()
45+
46+
cases = [
47+
["abc", "a#b", "", "hello"],
48+
["", ""], # 빈 문자열 2개
49+
["#", "##", "###"], # 해시 포함
50+
]
51+
for arr in cases:
52+
enc = sol.encode(arr)
53+
dec = sol.decode(enc)
54+
print(arr == dec, arr, "->", enc[:50] + ("..." if len(enc) > 50 else ""))
55+
56+

group-anagrams/hyogshin.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""
2+
풀이 방법
3+
- ord 함수를 이용해서 캐릭터 수를 기준으로 애너그램 구분
4+
- tuple 활용해서 키로 사용
5+
6+
시간 복잡도: O(n * k)
7+
- 중첩 for loop: O(n * k)
8+
9+
공간 복잡도: O(n)
10+
- cnt 문자열: O(1)
11+
- groups dict: O(n)
12+
"""
13+
14+
from collections import defaultdict
15+
from typing import List
16+
class Solution:
17+
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
18+
groups = defaultdict(list)
19+
for s in strs:
20+
cnt = [0] * 26
21+
for ch in s:
22+
cnt[ord(ch) - ord('a')] += 1
23+
groups[tuple(cnt)].append(s)
24+
return list(groups.values())
25+
26+
if __name__ == "__main__":
27+
sol = Solution()
28+
print(sol.groupAnagrams(["eat","tea","tan","ate","nat","bat"]))
29+
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
"""
2+
풀이 방법
3+
- insert: 입력된 단어의 캐릭터로 for loop을 돌아 node.children에 없는 캐릭터라면 추가하고 있다면 node.isEnd = True
4+
- search: 입력된 단어를 캐릭터 단위로 for loop을 돌고 node.children에 없다면 바로 False 반환, 만약 모든 캐릭터가 있는 경우 단어있는 확인하기 위해 isEnd 체크
5+
- startsWith: 입력된 prefix로 for loop을 돌아 node.children에 없다면 바로 False 반환
6+
7+
시간 복잡도: O(n)
8+
- for loop -> O(n)
9+
10+
공간 복잡도: O(n)
11+
- Trie를 저장하는 공간 -> O(n)
12+
"""
13+
14+
from typing import List
15+
16+
class TrieNode:
17+
def __init__(self):
18+
self.children = {}
19+
self.isEnd = False
20+
21+
class Trie:
22+
23+
def __init__(self):
24+
self.root = TrieNode()
25+
26+
def insert(self, word: str) -> None:
27+
node = self.root
28+
for ch in word:
29+
if ch not in node.children:
30+
node.children[ch] = TrieNode()
31+
node = node.children[ch]
32+
node.isEnd = True
33+
34+
def search(self, word: str) -> bool:
35+
node = self.root
36+
for ch in word:
37+
if ch not in node.children:
38+
return False
39+
node = node.children[ch]
40+
return node.isEnd
41+
42+
def startsWith(self, prefix: str) -> bool:
43+
node = self.root
44+
for ch in prefix:
45+
if ch not in node.children:
46+
return False
47+
node = node.children[ch]
48+
return True
49+
50+
if __name__ == "__main__":
51+
trie = Trie()
52+
53+
# insert & search 테스트
54+
trie.insert("apple")
55+
print(trie.search("apple")) # True
56+
print(trie.search("app")) # False
57+
print(trie.startsWith("app")) # True
58+
59+
trie.insert("app")
60+
print(trie.search("app")) # True
61+
62+
# 추가 케이스
63+
trie.insert("application")
64+
print(trie.search("application")) # True
65+
print(trie.startsWith("appl")) # True
66+
print(trie.search("apply")) # False
67+
68+
trie.insert("bat")
69+
trie.insert("bath")
70+
print(trie.search("bat")) # True
71+
print(trie.startsWith("ba")) # True
72+
print(trie.search("bad")) # False
73+

word-break/hyogshin.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
풀이 방법
3+
- for 루프로 주어진 문자열을 돌면서 wordDict에 있는 단어와 매칭되면 해당 인덱스 dp를 True로 변경
4+
- True인 dp로부터 또 다른 단어가 사전에 매칭되면 다시 dp를 True로 변경
5+
- 문자열 길이 인덱스의 dp[len(str)] 가 True인 경우 모든 단어가 사전에 있는 단어로 대체 가능하므로 True 반환
6+
7+
시간 복잡도: O(n^2)
8+
- for loop * n + for loop * 최대 n -> O(n^2)
9+
- s[j:i] 를 wordDict에서 찾는 행위 -> O(m)
10+
11+
공간 복잡도: O(n)
12+
- dp 배열 크기 -> O(n)
13+
- wordDict 크기 -> O(m)
14+
"""
15+
16+
from typing import List
17+
18+
class Solution:
19+
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
20+
dp = [False] * (len(s) + 1)
21+
dp[0] = True
22+
for i in range(1, len(s) + 1):
23+
for j in range(i):
24+
if dp[j] and s[j:i] in wordDict:
25+
dp[i] = True
26+
break
27+
return dp[len(s)]
28+

0 commit comments

Comments
 (0)