Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions best-time-to-buy-and-sell-stock/devyejin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# time complexity : O(n)
# space complexity : O(1)
from typing import List


class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
min_price = prices[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prices가 빈 배열일 경우 prices[0] 접근에서 IndexError 발생 가능 → 입력 검증 필요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문제 조건에서 prices 길이가 1이상이라는 문구가 있어서 저런식으로 처리하긴했는데, 그래도 안전하게 검증 로직 넣는게 좋을까요?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 제가 조건을 못 봤네요. 이 문제에서는 해당 사항 고려하지 않으셔도 됩니다.

max_profit = 0

for i in range(1, n):
min_price = min(min_price, prices[i])
max_profit = max(max_profit, prices[i] - min_price)

return max_profit
33 changes: 33 additions & 0 deletions encode-and-decode-strings/devyejin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
class Solution:
"""
@param: strs: a list of strings
@return: encodes a list of strings to a single string.
"""

def encode(self, strs):
# write your code here
result = ""
for s in strs:
result += str(len(s)) + "@" + s
return result

"""
@param: str: A string
@return: decodes a single string to a list of strings
"""

def decode(self, str):
# write your code here
result = []
i = 0
while i < len(str):
j = i
# 시작점 아닌 경우
while str[j] != "@":
j += 1
# 시작점인 경우
length = int(str[i:j])
word = str[j + 1: j + 1 + length]
result.append(word)
i = j + 1 + length
return result
21 changes: 21 additions & 0 deletions group-anagrams/devyejin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from typing import List
from collections import Counter, defaultdict

# class Solution:
# def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
#
# dict_anagrams = defaultdict(list)
# for idx, word in enumerate(strs):
# key = tuple(sorted(Counter(word).items()))
# dict_anagrams[key].append(word)
#
# return list(dict_anagrams.values())
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:

dict_anagrams = defaultdict(list)
for word in strs:
key = "".join(sorted(word))
dict_anagrams[key].append(word)

return list(dict_anagrams.values())
61 changes: 61 additions & 0 deletions implement-trie-prefix-tree/devyejin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
class TrieNode:
def __init__(self):
self.isEnd = False
self.links = {}


class Trie:

def __init__(self):
self._root = TrieNode()

def _recurAdd(self, node: TrieNode, word: str) -> None:
if not word:
node.isEnd = True
return

ch = word[0]
# 부모 노드의 자식에 있는지 확인
next_link = node.links.get(ch)

if not next_link:
node.links[ch] = TrieNode()
next_link = node.links[ch]

self._recurAdd(next_link, word[1:])

def insert(self, word: str) -> None:
if not word:
return

self._recurAdd(self._root, word)

def _recurSearch(self, node: TrieNode, word: str) -> bool:
if not word:
return node.isEnd

ch = word[0]
next_link = node.links.get(ch)
if next_link:
return self._recurSearch(next_link, word[1:])
return False

def search(self, word: str) -> bool:
if not word:
return False

return self._recurSearch(self._root, word)

def startsWith(self, prefix: str) -> bool:
node = self._root
for ch in prefix:
if ch not in node.links:
return False
node = node.links[ch]
return True

# 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)
24 changes: 24 additions & 0 deletions word-break/devyejin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from typing import List


class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
def dfs(subs: str):
if subs in memo:
return memo[subs]

if not subs:
return True

for word in wordDict:
if subs.startswith(word):
if dfs(subs[len(word):]):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메모이제이션을 이용한 탑다운 DP로 풀이하신 것으로 보이네요! 코드가 명확하여 이해하기 쉬웠습니다 ㅎㅎㅎ

추가로 이 문제에 DP 뿐만 아니라 #256 문제에서 다뤘던 트라이도 함께 활용한다면 매 단계마다 wordDict 전체를 순회하며 subs.startswith(word)를 하는 부분을 최적화 할 수 있습니다! 맨 처음에 wordDict를 트라이에 넣어두면 순회할 필요 없이 트라이를 따라 내려가며 prefix만 확인할 수 있기 때문인데요, 한 번 이렇게도 풀어보셔도 좋을 것 같습니다~!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상세한 피드백 감사드립니다! 풀면서도 비효율적인 부분이 있다 싶었는데 트라이로 최적화할 수 있다는 건 생각 못했네요. 알려주셔서 감사합니다! 트라이로 한 번 풀어보겠습니다. 😄

memo[subs] = True
return True

memo[subs] = False
return False

memo = {}
return dfs(s)