diff --git a/coin-change/ZetBe.py b/coin-change/ZetBe.py new file mode 100644 index 0000000000..f9caf657cd --- /dev/null +++ b/coin-change/ZetBe.py @@ -0,0 +1,38 @@ +''' +문제: 주어진 동전 종류로 특정 금액을 만들기 위한 최소 동전 개수를 구하시오. +풀이: 동적 계획법(DP)을 사용하여 각 금액에 대해 최소 동전 개수를 계산합니다. 만약 특정 금액을 만들 수 없다면 -1을 반환합니다. +시간 복잡도: O(n * m), n은 금액(amount), m은 동전 종류의 개수입니다. 각 금액에 대해 모든 동전을 확인하므로 전체 시간 복잡도는 O(n * m)입니다. +공간 복잡도: O(n), 금액(amount)까지의 최소 동전 개수를 저장하는 DP 배열을 사용하므로 공간 복잡도는 O(n)입니다. +사용한 자료구조: 배열(DP 배열) +''' + + +class Solution: + def coinChange(self, coins: List[int], amount: int) -> int: + if amount == 0: + return 0 + if len(coins) == 1 and coins[0] > amount: + return -1 + if amount in coins: + return 1 + + dp = [0 for i in range(amount+1)] + + for i in range(amount+1): + for j in range(len(coins)): + if i == 0 and coins[j] < amount: + dp[coins[j]] = 1 + elif i > 0 and 0 <= i+coins[j] <= amount: + if dp[i] > 0 and dp[i+coins[j]] > 0: + dp[i+coins[j]] = min(dp[i+coins[j]], dp[i]+1) + elif dp[i] > 0 and dp[i+coins[j]] == 0: + dp[i+coins[j]] = dp[i]+1 + + + + + if dp[amount] == 0: + return -1 + return dp[amount] + + diff --git a/find-minimum-in-rotated-sorted-array/ZetBe.py b/find-minimum-in-rotated-sorted-array/ZetBe.py new file mode 100644 index 0000000000..3213501e9f --- /dev/null +++ b/find-minimum-in-rotated-sorted-array/ZetBe.py @@ -0,0 +1,30 @@ +''' +Docstring for find-minimum-in-rotated-sorted-array.ZetBe +문제: 회전된 정렬 배열에서 최솟값을 찾으시오. +풀이: 이진 탐색을 사용하여 회전된 배열에서 최솟값을 효율적으로 찾습니다. +시간 복잡도: O(log n), n은 배열의 길이입니다. 이진 탐색을 사용하여 절반씩 탐색 범위를 줄이므로 전체 시간 복잡도는 O(log n)입니다. +공간 복잡도: O(1), 추가적인 공간을 사용하지 않으므로 공간 복잡도는 O(1)입니다. +사용한 자료구조: 배열 +추가로, while문 내부에서 무조건 리턴하기 떄문에, while문 이후 도달하는 경우는 없다. +''' + + +class Solution: + def findMin(self, nums: List[int]) -> int: + n = len(nums) + if nums[0] <= nums[n-1]: + return nums[0] + + r, l = 0, n-1 + + while r < l: + now = (r+l)//2 + if now < n-1 and nums[now] > nums[now+1]: + return nums[now+1] + + if now < n-1 and nums[0] > nums[now] <= nums[now+1]: + l = now + elif now < n-1 and nums[0] <= nums[now] <= nums[now+1]: + r = now + + diff --git a/maximum-depth-of-binary-tree/ZetBe.py b/maximum-depth-of-binary-tree/ZetBe.py new file mode 100644 index 0000000000..98201ee24e --- /dev/null +++ b/maximum-depth-of-binary-tree/ZetBe.py @@ -0,0 +1,32 @@ +''' +문제: 이진 트리의 최대 깊이를 구하시오. +풀이: 깊이 우선 탐색(DFS)을 사용하여 트리의 각 경로를 탐색하고, 최대 깊이를 갱신합니다. +시간 복잡도: O(n), n은 트리의 노드 수입니다. 모든 노드를 한 번씩 방문하므로 전체 시간 복잡도는 O(n)입니다. +공간 복잡도: O(h), h는 트리의 높이입니다. 재귀 호출 스택이 최대 h 깊이까지 쌓일 수 있으므로 공간 복잡도는 O(h)입니다. +사용한 자료구조: 함수(재귀 호출 스택) +''' + + +# 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 + answ = 1 + def dfs(root, a): + nonlocal answ + if root.left: + dfs(root.left, a+1) + if root.right: + dfs(root.right, a+1) + answ = max(answ, a) + return a + dfs(root, 1) + return answ + + diff --git a/merge-two-sorted-lists/ZetBe.py b/merge-two-sorted-lists/ZetBe.py new file mode 100644 index 0000000000..a65b19a65a --- /dev/null +++ b/merge-two-sorted-lists/ZetBe.py @@ -0,0 +1,37 @@ +''' +문제: 두 개의 정렬된 연결 리스트를 병합하여 하나의 정렬된 연결 리스트를 만드시오. +풀이: 두 연결 리스트의 노드를 비교하면서 작은 값을 가진 노드를 결과 리스트에 추가하는 방식으로 병합합니다. +시간 복잡도: O(n + m), n과 m은 각각 두 연결 리스트의 길이입니다. 두 리스트의 모든 노드를 한 번씩 방문하므로 전체 시간 복잡도는 O(n + m)입니다. +공간 복잡도: O(1), 추가적인 연결 리스트를 생성하지 않고 기존 노드들을 재사용하므로 공간 복잡도는 O(1)입니다. +사용한 자료구조: 연결 리스트 +''' + + + +# 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]: + if list2 == None: + return list1 + if list1 == None: + return list2 + + if list1.val <= list2.val: + a, b = list1, list2 + else: + b, a = list1, list2 + # 얕은 복사 활용 (중요해보임) + result = a + while a != None and b != None: + if a.next != None and a.val <= b.val and a.next.val <= b.val: + a = a.next + else: + a.next, b = b, a.next + a = a.next + return result + + diff --git a/word-search/ZetBe.py b/word-search/ZetBe.py new file mode 100644 index 0000000000..11820575f7 --- /dev/null +++ b/word-search/ZetBe.py @@ -0,0 +1,37 @@ +''' +Docstring for word-search.ZetBe +문제: 2D 보드에서 단어를 찾으시오. +풀이: 깊이 우선 탐색(DFS)을 사용하여 보드의 각 셀에서 시작하여 단어를 찾습니다. 방문한 셀은 다시 방문하지 않도록 표시합니다. +시간 복잡도: O(m * n * 3^k), m과 n은 보드의 행과 열의 수, k는 단어의 길이입니다. 각 셀에서 시작하여 최대 3가지 방향으로 탐색할 수 있으므로 전체 시간 복잡도는 O(m * n * 3^k)입니다. +공간 복잡도: O(k), k는 단어의 길이입니다. 재귀 호출 스택이 최대 k 깊이까지 쌓일 수 있으므로 공간 복잡도는 O(k)입니다. +사용한 자료구조: 함수(재귀 호출 스택), 2D 리스트(방문 표시) +''' + +class Solution: + def exist(self, board: List[List[str]], word: str) -> bool: + answ = False + dx, dy = [0, 1, -1, 0], [1, 0, 0, -1] + def dfs(x, y, i, v): + nonlocal answ + if i == len(word): + answ = True + return True + if board[y][x] != word[i-1]: + return False + for j in range(4): + ny, nx = y+dy[j], x+dx[j] + if 0 <= ny < len(board) and 0 <= nx < len(board[0]) and v[ny][nx] == 0 and board[ny][nx] == word[i]: + v[ny][nx] = 1 + dfs(nx, ny, i+1, v) + v[ny][nx] = 0 + + for i in range(len(board)): + for j in range(len(board[0])): + v = [[0 for i in range(len(board[0]))] for j in range(len(board))] + if board[i][j] == word[0]: + v[i][j] = 1 + dfs(j, i, 1, v) + + return answ + +