-
-
Notifications
You must be signed in to change notification settings - Fork 361
[parkhojeong] WEEK 05 Solutions #2768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0630c80
6328dc6
905eb33
6dd411d
f143fb4
78d8ad5
8facb2e
50caae0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| class Solution: | ||
| def maxProfit(self, prices: List[int]) -> int: | ||
| min_price = 10_000 | ||
| max_profit = 0 | ||
| for cur_price in prices: | ||
| if max_profit < cur_price - min_price: | ||
| max_profit = cur_price - min_price | ||
|
|
||
| if cur_price < min_price: | ||
| min_price = cur_price | ||
|
|
||
| return max_profit |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 숫자길이를 고정값으로 하니까 파싱이 확실히 간단하고 쉬워지네요!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| class Codec: | ||
| def encode(self, strs: List[str]) -> str: | ||
| """Encodes a list of strings to a single string. | ||
| """ | ||
| encoded = "" | ||
| for s in strs: | ||
| encoded += f"{len(s):03d}{s}" | ||
| return encoded | ||
|
|
||
| def decode(self, s: str) -> List[str]: | ||
| """Decodes a single string to a list of strings. | ||
| """ | ||
|
|
||
| decoded = [] | ||
| i = 0 | ||
| while i < len(s): | ||
| s_start_idx = i + 3 | ||
| s_len = int(s[i:s_start_idx]) | ||
| decoded.append(s[s_start_idx:s_start_idx + s_len]) | ||
|
|
||
| i = s_start_idx + s_len | ||
|
|
||
| return decoded | ||
|
|
||
|
|
||
| # Your Codec object will be instantiated and called as such: | ||
| # codec = Codec() | ||
| # codec.decode(codec.encode(strs)) |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| class Solution: | ||
| def groupAnagrams(self, strs: List[str]) -> List[List[str]]: | ||
| anagram_dic = {} | ||
| for s in strs: | ||
| key = "".join(sorted(s)) | ||
| anagram_dic.setdefault(key, []).append(s) | ||
|
|
||
| return list(anagram_dic.values()) |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 추가 Node없이 할수 있다면 그렇게 하는게 더 좋지 않을까 싶어요!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 추가 Node 없이 한다는게 무슨 말씀일까요?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| class Node: | ||
| def __init__(self, s: str): | ||
| self.isLast: bool = False | ||
| self.childs: dict[str, Node] = {} | ||
|
|
||
| def addChild(self, s: str): | ||
| if self.getChild(s) is not None: | ||
| return | ||
|
|
||
| node = Node(s) | ||
| self.childs[s] = node | ||
|
|
||
| def getChild(self, s: str) -> Node | None: | ||
| if s not in self.childs: | ||
| return None | ||
|
|
||
| return self.childs[s] | ||
|
|
||
| def setIsLast(self, isLast: bool): | ||
| self.isLast = isLast | ||
|
|
||
| def getIsLast(self) -> bool: | ||
| return self.isLast | ||
|
|
||
|
|
||
| class Trie: | ||
| root: Node | ||
|
|
||
| def __init__(self): | ||
| self.root = Node("") | ||
|
|
||
| def insert(self, word: str) -> None: | ||
| node = self.root | ||
| for i in range(len(word)): | ||
| ch = word[i] | ||
| if node.getChild(ch) is None: | ||
| node.addChild(ch) | ||
|
|
||
| node = node.getChild(ch) | ||
| if i == len(word) - 1: | ||
| node.setIsLast(True) | ||
|
|
||
| def findNode(self, word) -> Node | None: | ||
| node = self.root | ||
| for ch in word: | ||
| node = node.getChild(ch) | ||
| if node is None: | ||
| return None | ||
|
|
||
| return node | ||
|
|
||
| def search(self, word: str) -> bool: | ||
| node = self.findNode(word) | ||
| if node is None or not node.getIsLast(): | ||
| return False | ||
|
|
||
| return True | ||
|
|
||
| def startsWith(self, prefix: str) -> bool: | ||
| return self.findNode(prefix) is not None | ||
|
|
||
|
|
||
|
|
||
| # Your Trie object will be instantiated and called as such: | ||
| # obj = Trie() | ||
| # obj.insert(word) | ||
| # param_2 = obj.search(word) | ||
| # param_3 = obj.startsWith(prefix) |
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 풀이 n이랑 m이 뭔지는 몰라도
다만 이거 trie 이용해서 비슷한 수준까지 최적화는 가능하세요!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 리뷰 감사합니다. 그러네요. 말씀하신 것처럼 놓치는 케이스가 있어서 split 사용하지 않고 다른 방식으로 풀어보았습니다. 8facb2e
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏷️ 알고리즘 패턴 분석
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| class Solution: | ||
| def wordBreak(self, s: str, wordDict: List[str]) -> bool: | ||
| word_len_set = set(len(word) for word in wordDict) | ||
| word_set = set(word for word in wordDict) | ||
| visited = set() | ||
|
|
||
| def dfs(s: str): | ||
| if len(s) == 0: | ||
| return True | ||
|
|
||
| if s in visited: | ||
| return False | ||
|
|
||
| visited.add(s) | ||
|
|
||
| for word_len in word_len_set: | ||
| if s[:word_len] not in word_set: | ||
| continue | ||
|
|
||
| if dfs(s[word_len:]): | ||
| return True | ||
|
|
||
| return False | ||
|
|
||
| return dfs(s) |

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🏷️ 알고리즘 패턴 분석
📊 시간/공간 복잡도 분석
풀이 1:
Solution.maxProfit— Time: O(n) / Space: O(1)피드백: 한 번의 루프에서 현재 가격 대비 최소 가격과 누적 최대 이익을 갱신합니다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 2:
Codec.encode— Time: O(total_chars) / Space: O(total_chars)피드백: 각 문자열 길이를 3자리로 고정해 파싱이 용이하게 구성되어 있습니다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 3:
Codec.decode— Time: O(total_chars) / Space: O(total_chars)피드백: 인덱스 기반 파싱으로 전체 문자열을 순차적으로 읽습니다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 4:
Solution.groupAnagrams— Time: O(n * k log k) / Space: O(n * k)피드백: 각 문자열을 정렬해 그룹화하므로 전체 시간은 각 문자열의 길이에 따라 달라집니다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 5:
Trie.insert— Time: O(m) / Space: O(m * sigma)피드백: 단어 길이 m에 비례하는 시간과 노드 개수에 따른 공간을 사용합니다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 6:
Trie.findNode— Time: O(m) / Space: O(1)피드백: 연속 탐색으로 최악에서도 선형적으로 진행됩니다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 7:
Trie.search— Time: O(m) / Space: O(1)피드백: 끝 노드의 isLast를 확인해 정확한 단어 여부를 반환합니다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 8:
Trie.startsWith— Time: O(m) / Space: O(1)피드백: 접두어 존재 여부는 findNode 호출로 판단합니다.
개선 제안: 현재 구현이 적절해 보입니다.
풀이 9:
Solution.wordBreak— Time: O(n * w) / Space: O(n)피드백: 단어 길이 조합에 따라 분기 폭이 커질 수 있지만, 재방문 방지를 위해 방문 집합을 사용합니다.
개선 제안: 현재 구현이 적절해 보입니다.