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
32 changes: 32 additions & 0 deletions best-time-to-buy-and-sell-stock/devyulbae.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
Blind 75 - Best Time to Buy and Sell Stock
https://leetcode.com/problems/best-time-to-buy-and-sell-stock/

시간복잡도 : O(n)
공간복잡도 : O(1)
풀이 : 한 번의 순회로 해결

prices = [7,1,5,3,6,4]

price | min | max_profit
7 | 7 | 0
1 | 1 | 0
5 | 1 | 4
3 | 1 | 4
6 | 1 | 5
4 | 1 | 5

"""
from typing import List

class Solution:
def maxProfit(self, prices: List[int]) -> int:
max_profit = 0
min_price = prices[0]

for price in prices:
min_price = min(min_price, price)
max_profit = max(max_profit, price - min_price)

return max_profit

19 changes: 19 additions & 0 deletions coin-change/devyulbae.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
Blind 75 - Coin Change
LeetCode Problem Link: https://leetcode.com/problems/coin-change/
시간복잡도 : O(n*m) (n: amount, m: len(coins))
공간복잡도 : O(n)

"""
from typing import List
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
dp = [float('inf')] * (amount + 1)
dp[0] = 0

for coin in coins: # 각 동전마다
for x in range(coin, amount + 1): # 금액 1 coin부터 amount까지
dp[x] = min(dp[x], dp[x - coin] + 1) # 해당 금액을 만들기 위한 최소 동전 개수 갱신

return dp[amount] if dp[amount] != float('inf') else -1 # amount를 만들 수 없는 경우 -1 반환

38 changes: 37 additions & 1 deletion decode-ways/devyulbae.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
"""
Blind75 - Decode Ways
https://leetcode.com/problems/decode-ways/
시간복잡도: O(n)
공간복잡도: O(n)
풀이 : 메모이제이션 + DFS를 활용한 재귀 풀이

아..DP로는 못 풀겠어서 풀이 봤습니다. 강의나 책을 봐야겠군요
class Solution:
def numDecodings(self, s: str) -> int:

dp = [0] * len(s) + [1]
for start in reversed(range(len(s))):
if s[start] == "0":
dp[start] = 0
elif start + 1 < len(s) and int(s[start : start + 2]) < 27:
dp[start] = dp[start + 1] + dp[start + 2]
else:
dp[start] = dp[start + 1]
return dp[0]
"""
class Solution:
def numDecodings(self, s: str) -> int:
memo = {len(s): 1}

def dfs(start):
if start in memo:
return memo[start]

if s[start] == "0":
memo[start] = 0
elif start + 1 < len(s) and int(s[start : start + 2]) < 27:
memo[start] = dfs(start + 1) + dfs(start + 2)
else:
memo[start] = dfs(start + 1)
return memo[start]

return dfs(0)


Empty file.
24 changes: 24 additions & 0 deletions find-minimum-in-rotated-sorted-array/devyulbae.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""
Blind 75 - Find Minimum in Rotated Sorted Array
LeetCode Problem Link: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/
시간복잡도 : O(log n)
공간복잡도 : O(1)
풀이 : 이진 탐색
중간점 기준으로 nums[mid-1] > nums[mid] 이면 mid가 최소값
그렇지 않으면 왼쪽 절반이 정렬되어 있는지 확인해서 왼쪽 절반 or 오른쪽 절반으로 탐색 범위를 좁혀나감
만약 발견되지 않았다면 nums[0]이 최소값
"""
from typing import List
class Solution:
def findMin(self, nums: List[int]) -> int:
left, right = 1, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid -1] > nums[mid]:
return nums[mid]
if nums[0] < nums[mid]:
left = mid + 1
else:
right = mid - 1
return nums[0]

24 changes: 24 additions & 0 deletions group-anagrams/devyulbae.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""
Blind 75 - Group Anagrams
LeetCode Problem: https://leetcode.com/problems/group-anagrams/
시간복잡도 : O(N * K) (N은 strs의 길이, K는 strs 내 문자열의 최대 길이)
공간복잡도 : O(N * K)
풀이 : 해시맵을 이용한 풀이
ASCII 문자를 이용하여 각 문자열의 문자 개수를 세어 이를 키로 사용하여 해시맵에 저장한다

"""

from typing import List
from collections import defaultdict
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
anagrams = defaultdict(list)

for s in strs:
count = [0] * 26
for char in s:
count[ord(char) - ord('a')] += 1
anagrams[tuple(count)].append(s)

return list(anagrams.values())

Empty file.
24 changes: 24 additions & 0 deletions maximum-depth-of-binary-tree/devyulbae.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""
Blind 75 - Maximum Depth of Binary Tree
LeetCode Problem Link: https://leetcode.com/problems/maximum-depth-of-binary-tree/
시간복잡도 : O(n)
공간복잡도 : O(n)
풀이 : 재귀를 이용한 깊이 우선 탐색(DFS)
자식 노드부터 부모 노드로 거슬러 올라가며 최대 깊이를 계산합니다.
종료 조건 - left와 right가 모두 None인 경우 (1+max(0,0))을 반환하며 재귀가 종료됩니다.
"""

from typing import Optional
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0

return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))

35 changes: 35 additions & 0 deletions merge-two-sorted-lists/devyulbae.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""
Blind 75 - Merge Two Sorted Lists
LeetCode Problem Link: https://leetcode.com/problems/merge-two-sorted-lists/
시간복잡도 : O(n+m)
공간복잡도 : O(1)
풀이 : (알고달레 답안)
각 링크드 리스트에 포인터를 두고, 더 작은 값을 가진 노드를 결과 리스트에 추가하다가 한 쪽 리스트가 끝나면 나머지 리스트를 결과 리스트에 추가한다.
마지막에 첫번째 노드를 반환한다.
"""
from typing import Optional

# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next

class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode()
tail = dummy

while list1 and list2:
if list1.val < list2.val:
tail.next = list1
list1 = list1.next
else:
tail.next = list2
list2 = list2.next

tail = tail.next

tail.next = list1 or list2
return dummy.next

23 changes: 23 additions & 0 deletions word-break/devyulbae.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""
Blind 75 - Word Break
LeetCode Problem: https://leetcode.com/problems/word-break/
시간복잡도 : O(n^2)
공간복잡도 : O(n)
풀이 : 다이나믹 프로그래밍을 이용한 풀이
문자열 s의 길이를 n이라 할 때, dp[i]를 s의 처음부터 i-1번째 문자까지의 부분 문자열이
단어 사전에 있는 단어들로 구성될 수 있는지를 나타내는 불리언 값이라고 정의한다.
"""
from typing import List
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
dp = [False] * (len(s) + 1)
dp[0] = True

word_set = set(wordDict)
for i in range(1, len(s) + 1):
for j in range(i):
if dp[j] and s[j:i] in word_set: # 0~j-1까지 문자열이 단어사전에 있고, j~i-1까지 문자열이 단어사전에 있는 경우
dp[i] = True
break

return dp[len(s)]
50 changes: 50 additions & 0 deletions word-search/devyulbae.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""
Blind 75 - Word Search
LeetCode Problem Link: https://leetcode.com/problems/word-search/
시간복잡도 :
공간복잡도 :
풀이 : DFS + 백트래킹
1. 전체 순회하여 단어의 첫 글자와 일치하는 지점 찾기
2. 첫 글자 List에 대해서 DFS 수행하여 있다면 return True
3. 없다면 return False
visited를 별도로 저장하는 대신 board의 글자를 임시로 변경하여 방문처리(backtracking)
-> 잊지 말고 board[i][j] = char 로 원상복구 시키기
"""
from typing import List

class Solution:
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

def dfs(self, board, word, i, j, word_index):
# 종료 조건
if word_index == len(word):
return True

# 실패 조건
if (i < 0 or i >= len(board) or
j < 0 or j >= len(board[0]) or
board[i][j] != word[word_index]):
return False
char = board[i][j]
board[i][j] = '#'
# 4방향 탐색
for direction in range(4):
ni = i + self.dx[direction]
nj = j + self.dy[direction]
if self.dfs(board, word, ni, nj, word_index + 1):
board[i][j] = char
return True
board[i][j] = char
return False

def exist(self, board: List[List[str]], word: str) -> bool:
rows = len(board)
cols = len(board[0])

for i in range(rows):
for j in range(cols):
if self.dfs(board, word, i, j, 0):
return True
return False