From 75a496a51d75ffa9d5879b925ee819eeca16e453 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Sun, 10 Aug 2025 13:07:29 +0900 Subject: [PATCH 1/4] feat: Solve merge-two-sorted-lists problem --- merge-two-sorted-lists/hu6r1s.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 merge-two-sorted-lists/hu6r1s.py diff --git a/merge-two-sorted-lists/hu6r1s.py b/merge-two-sorted-lists/hu6r1s.py new file mode 100644 index 000000000..e63825fa9 --- /dev/null +++ b/merge-two-sorted-lists/hu6r1s.py @@ -0,0 +1,26 @@ +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + # 시간복잡도: O(n + m) -> 두 리스트의 모든 노드를 한 번씩 방문 + # 공간복잡도: O(1) -> 기존 노드 재배치, 추가 메모리 거의 없음 + def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: + merged_list = ListNode() + tail = merged_list + + 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 + + if list1: + tail.next = list1 + else: + tail.next = list2 + return merged_list.next From 0f3f7541ffd8ccc73bec24cee890f9fa76556bc9 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Tue, 12 Aug 2025 21:31:34 +0900 Subject: [PATCH 2/4] feat: Solve maximum-depth-of-binary-tree problem --- maximum-depth-of-binary-tree/hu6r1s.py | 50 ++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 maximum-depth-of-binary-tree/hu6r1s.py diff --git a/maximum-depth-of-binary-tree/hu6r1s.py b/maximum-depth-of-binary-tree/hu6r1s.py new file mode 100644 index 000000000..60a096a5c --- /dev/null +++ b/maximum-depth-of-binary-tree/hu6r1s.py @@ -0,0 +1,50 @@ +from collections import deque + +# 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 + + def bfs(n): + queue = deque([n]) + depth = 0 + + while queue: + depth += 1 + for _ in range(len(queue)): + node = queue.popleft() + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) + return depth + + def dfs(n): + stack = [n] + max_depth = 0 + visited = {n: 1} + + while stack: + node = stack.pop() + depth = visited[node] + max_depth = max(max_depth, depth) + if node.left: + visited[node.left] = depth + 1 + stack.append(node.left) + if node.right: + visited[node.right] = depth + 1 + stack.append(node.right) + return max_depth + + return dfs(root) + + +""" +bfs 방식으로 left나 right가 있으면 스택에 넣고 depth + 1, dfs보다 비효율인 듯 +""" From a5c5aba5e6a37a9f46c2c60f5658a677ade0d474 Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Wed, 13 Aug 2025 20:52:28 +0900 Subject: [PATCH 3/4] feat: Solve find-minimum-in-rotated-sorted-array problem --- .../hu6r1s.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 find-minimum-in-rotated-sorted-array/hu6r1s.py diff --git a/find-minimum-in-rotated-sorted-array/hu6r1s.py b/find-minimum-in-rotated-sorted-array/hu6r1s.py new file mode 100644 index 000000000..9ca4f5bdf --- /dev/null +++ b/find-minimum-in-rotated-sorted-array/hu6r1s.py @@ -0,0 +1,55 @@ +class Solution: + """ + [3, 4, 5, 1, 2] -> [2, 3, 4, 5, 1] -> [1, 2, 3, 4, 5] + 1. 큐의 rotate 이용 -> 회전 전의 첫 요소가 회전 후의 요소 비교 + 시간복잡도: O(n^2) + - while 루프가 최대 n번 반복 가능 + - deque.rotate(±1) 연산이 O(n) 시간 소요 + - 따라서 전체는 O(n) * O(n) = O(n^2) + 공간복잡도: O(n) + - 입력 배열을 deque로 변환 → 추가로 O(n) 공간 사용 + - 나머지는 상수 공간 + """ + """ + def findMin(self, nums: List[int]) -> int: + nums = deque(nums) + if len(nums) == 1: + return nums[0] + + while True: + cur = nums[0] + nums.rotate(1) + if cur < nums[0]: + nums.rotate(-1) + return nums[0] + """ + + """ + 2. 요소별로 이전 값과 현재 값을 비교하여 작은 값이 나오면 그 값이 첫번쨰 요소, 즉 가장 작은 요소가 됨 + 시간복잡도: O(n) + - 최악의 경우 배열 전체를 한 번 순회해야 함 + - n = len(nums) + 공간복잡도: O(1) + - 추가로 사용하는 변수는 i와 몇 개의 상수형 변수뿐 + """ + """ + def findMin(self, nums: List[int]) -> int: + for i in range(1, len(nums)): + if nums[i - 1] > nums[i]: + return nums[i] + return nums[0] + """ + """ + 3. 이분탐색을 사용하는 방법 + """ + def findMin(self, nums: List[int]) -> int: + start, end = 1, len(nums) - 1 + while start <= end: + mid = (start + end) // 2 + if nums[mid - 1] > nums[mid]: + return nums[mid] + if nums[0] < nums[mid]: + start = mid + 1 + else: + end = mid - 1 + return nums[0] From 9d9a59678394953ac597aad7ef6550d86070684f Mon Sep 17 00:00:00 2001 From: hu6r1s Date: Thu, 14 Aug 2025 21:16:12 +0900 Subject: [PATCH 4/4] feat: Solve word-search problem --- word-search/hu6r1s.py | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 word-search/hu6r1s.py diff --git a/word-search/hu6r1s.py b/word-search/hu6r1s.py new file mode 100644 index 000000000..1f8c620f8 --- /dev/null +++ b/word-search/hu6r1s.py @@ -0,0 +1,46 @@ +class Solution: + """ + 1. dfs 방식 + dx = [1, -1, 0, 0], dy = [0, 0, 1, -1], visited = [[False] * m for _ in range(n)] + 4방향으로 가면서 해당 요소에 단어가 없으면 false + 방문한 적이 없어야 하고, + + 시간복잡도: O(N * L * 4^L) + - N: 보드 크기 (n*m) + - L: 단어 길이 + - 모든 좌표에서 DFS 시작 (N회) × 4방향 분기 (4^L) × 슬라이싱 비용 (O(L)) + 공간복잡도: O(N + L^2) + - visited 배열 O(N) + - 재귀 호출 스택 O(L) + - 문자열 슬라이싱으로 인한 추가 메모리 O(L^2) + + """ + def exist(self, board: List[List[str]], word: str) -> bool: + n, m = len(board), len(board[0]) + visited = [[False] * m for _ in range(n)] + dx, dy = [1, -1, 0, 0], [0, 0, 1, -1] + + def dfs(x, y, w): + if not w: + return True + if x < 0 or y < 0 or x >= n or y >= m: + return False + if visited[x][y] or board[x][y] != w[0]: + return False + + visited[x][y] = True + + for i in range(4): + nx = x + dx[i] + ny = y + dy[i] + if dfs(nx, ny, w[1:]): + return True + + visited[x][y] = False + return False + + for i in range(n): + for j in range(m): + if dfs(i, j, word): + return True + return False