From 9aa3b020ec6665c6f337112e1be2096bf993d1e7 Mon Sep 17 00:00:00 2001 From: Yunyoung Chung Date: Mon, 11 May 2026 16:47:08 +0900 Subject: [PATCH 1/6] [7th batch] week 11 - missing number --- missing-number/liza0525.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 missing-number/liza0525.py diff --git a/missing-number/liza0525.py b/missing-number/liza0525.py new file mode 100644 index 0000000000..b97a817e75 --- /dev/null +++ b/missing-number/liza0525.py @@ -0,0 +1,17 @@ +# 7기 풀이 +# 시간 복잡도: O(n) +# - nums의 전체 합을 계산할 때 nums의 길이 만큼 시간 소요 +# 공간 복잡도: O(1) +# - 계산에 필요한 변수 몇 개만 사용 +class Solution: + def missingNumber(self, nums: List[int]) -> int: + # nums에서 빠진 값까지 함께 더했을 때의 값 + # 최소값(0) + 최대값(len(nums))을 2로 나눈 후, nums의 개수 + 1(0 포함)의 개수만큼 곱한 값 + # 등차수열의 전체 합 + all_sum_nums = int(len(nums) / 2 * (len(nums) + 1)) + + # nums 리스트의 전체 합 + sum_nums = sum(nums) + + # 두 값의 차이가 곧 누락된 값 + return all_sum_nums - sum_nums From d97ebe7ba677b356fc29dfdf3298d0a7b89da2cb Mon Sep 17 00:00:00 2001 From: Yunyoung Chung Date: Wed, 13 May 2026 20:22:08 +0900 Subject: [PATCH 2/6] [7th batch] week 11 - reorder list --- reorder-list/liza0525.py | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 reorder-list/liza0525.py diff --git a/reorder-list/liza0525.py b/reorder-list/liza0525.py new file mode 100644 index 0000000000..1e89d136d4 --- /dev/null +++ b/reorder-list/liza0525.py @@ -0,0 +1,43 @@ +# 7기 풀이 +# 시간 복잡도: O(n) +# - head 리스트의 길이 만큼의 시간 복잡도가 든다. +# 공간 복잡도: O(1) +# - 변수 몇 개만 사용 +class Solution: + def reorderList(self, head: Optional[ListNode]) -> None: + """ + Do not return anything, modify head in-place instead. + """ + + # slow-fast를 이용해서 리스트의 중간 노드를 찾는다 + # fast는 두 칸, slow는 한 칸을 움직이며 fast가 끝 노드에 도달할 때까지 loop를 돌면 + # slow로 중간 노드 찾을 수 있다. + slow, fast = head, head + + while fast and fast.next: + slow = slow.next + fast = fast.next.next + + # 중간 노드부터 마지막 노드까지의 리스트를 reversing해준다. + # prev, curr로 노드 포인터를 잡아 리스트를 뒤집느다. + prev, curr = None, slow + + while curr: + next_ = curr.next + curr.next, prev = prev, curr + curr = next_ + + # 원본이었던 head와 prev(중간부터 뒤집은 리스트)를 번갈아 가며 붙여준다. + # head의 포인터는 first, prev의 포인터는 second로 지정 + first, second = head, prev + + # second의 리스트를 다 돌 때까지 노드를 서로 연결해주면 된다. + while second.next: + first_next = first.next + second_next = second.next + + first.next = second + second.next = first_next + + second = second_next + first = first_next From c5da7e79a7504553b70020d0f26ed08bf5e4dd22 Mon Sep 17 00:00:00 2001 From: Yunyoung Chung Date: Wed, 13 May 2026 21:56:03 +0900 Subject: [PATCH 3/6] [7th batch] week 11 - graph valid tree --- graph-valid-tree/liza0525.py | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 graph-valid-tree/liza0525.py diff --git a/graph-valid-tree/liza0525.py b/graph-valid-tree/liza0525.py new file mode 100644 index 0000000000..8640732831 --- /dev/null +++ b/graph-valid-tree/liza0525.py @@ -0,0 +1,51 @@ +from collections import defaultdict + +# 7기 풀이 +# 시간 복잡도: O(V + E) +# - 노드 개수(V) 및 엣지의 개수(E)만큼 탐색하므로 이에 따라 시간이 걸림 +# 공간 복잡도: O(V + E) +# - visited 노드의 개수(V)만큼, node_map는 엣지의 개수(E)만큼 생성함 +# - 재귀 스택은 최대 V만큼 생김 +class Solution: + def validTree(self, n: int, edges: List[List[int]]) -> bool: + visited = [0 for _ in range(n)] + node_map = defaultdict(list) # 노드 연결 정보 저장할 mapper + + for node1, node2 in edges: + # 각 엣지는 방향이 없으므로 양방향 정보 저장 + node_map[node1].append(node2) + node_map[node2].append(node1) + + def check_is_not_cycle(prev_node, node): + if visited[node]: + # node를 이미 방문했다면 cycle이 있다는 의미이므로 tree가 아님 + # False를 return한다 + return False + + visited[node] = 1 # 현재 노드 방문 확인 + + next_nodes = node_map[node] + if not next_nodes: + # 더이상 방문할 것이 없다는 의미로 + # 해당 탐색은 cycle 없이 끝났다는 것을 의미 + return True + + for next_node in next_nodes: + if prev_node == next_node: + # 양방향 노드 특성 상 prev_node 노드가 다음 노드와 같을 수 있다 + # 이 때는 체크하지 않고 넘어간다 + continue + + if not check_is_not_cycle(node, next_node): + # 재귀 함수의 결과가 False이면 False로 전파 + return False + + # 함수 내의 모든 로직의 실행이 끝났다면 싸이클이 없다는 의미이므로 + # True를 return + return True + + is_not_cycle = check_is_not_cycle(None, 0) + + # 싸이클이 없더라도 연결이 되지 않은 노드는 방문을 하지 않을 수 있기 때문에 + # visited에 0이 있는지 같이 확인하여 valid tree 여부를 return + return 0 not in visited if is_not_cycle else False From 0f17d56724e17ecb1b75891d1fd5e2604860e258 Mon Sep 17 00:00:00 2001 From: Yunyoung Chung Date: Fri, 15 May 2026 11:39:01 +0900 Subject: [PATCH 4/6] [7th batch] week 11 - merge intervals --- merge-intervals/liza0525.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 merge-intervals/liza0525.py diff --git a/merge-intervals/liza0525.py b/merge-intervals/liza0525.py new file mode 100644 index 0000000000..5ed856ca3e --- /dev/null +++ b/merge-intervals/liza0525.py @@ -0,0 +1,31 @@ +# 7기 풀이 +# 시간 복잡도: O(n log n) +# - merge하는 로직은 intervals의 길이(n)만큼의 시간 소요 +# - intervals를 sorting하는 로직은 n log n 만큼의 시간 소요 +# 공간 복잡도: O(1) +# - 결과 리스트(res) 제외, 몇 개의 변수만 사용 +class Solution: + def merge(self, intervals: List[List[int]]) -> List[List[int]]: + # 먼저 intervals를 오름차순으로 sorting한다. + # 각 요소의 첫번째 값을 기준으로 + intervals.sort() + + i, j = 0, 1 + res = [] + + # intervals를 탐색하는 i가 그 길이보다 작을 때 loop를 돈다 + while i < len(intervals): + curr_start, curr_end = intervals[i] # 첫번째 머지 대상을 기준으로 + while j < len(intervals): # j번째 요소들을 계속 머지함(범위 머지가 가능한 한) + next_start, next_end = intervals[j] + if curr_start <= next_start <= curr_end: # 다음 요소의 첫번째 값이 현재 요소 범위 내에 있을 때 + curr_end = max(curr_end, next_end) # 더 큰 범위로 머지 + else: # 그렇지 않으면 이번 텀에서의 머지가 완료된 것이므로 loop 탈출 + break + j += 1 # 머지가 가능한 한 j를 계속 올려준다. + + res.append([curr_start, curr_end]) # 머지 완료된 구간은 res에 담고 + i = j # 이번 loop에서 사용했던 j가 다음 루프의 i가 되고 + j = i + 1 # j는 i의 다음 인덱스부터 다시 머지를 할 수 있도록 변경 + + return res From 9ad0665211ffb8452b02a30482d5721316ae0f06 Mon Sep 17 00:00:00 2001 From: Yunyoung Chung Date: Fri, 15 May 2026 11:48:36 +0900 Subject: [PATCH 5/6] [7th batch] week 11 - binary tree maximum path sum --- binary-tree-maximum-path-sum/liza0525.py | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 binary-tree-maximum-path-sum/liza0525.py diff --git a/binary-tree-maximum-path-sum/liza0525.py b/binary-tree-maximum-path-sum/liza0525.py new file mode 100644 index 0000000000..bfe43020ef --- /dev/null +++ b/binary-tree-maximum-path-sum/liza0525.py @@ -0,0 +1,35 @@ +# 7기 풀이 +# 시간 복잡도: O(n) +# - 트리 전체를 탐색이므로 전체 노드 개수(n) 만큼 시간 소요 +# 공간 복잡도: O(h) +# - 트리의 높이(h)만큼 재귀 스택 쌓임 +# - 최악의 경우(편향 트리) O(n), 평균적으로 O(log n) +class Solution: + def maxPathSum(self, root: Optional[TreeNode]) -> int: + self.res = root.val # 결과 변수를 클래스 멤버 변수로 지정 + + # 후위 탐색을 이용해서 문제를 풀면 된다 + def postorder(node): + if not node: # 노드가 None인 경우는 0을 리턴해준다 + return 0 + + # 자식 노드들 각각의 최대합을 먼저 계산한다. + # 자식들의 최대합이 음수인 경우는 현재 노드의 최대합 계산에 방해가 되므로 + # 0과 비교하여 더 큰 값을 저장하도록 한다 + left_total = max(postorder(node.left), 0) + right_total = max(postorder(node.right), 0) + + # 지금까지의 최대합(self.res)와 자식 노드 및 현재 노드 val의 합을 비교하여 + # 더 큰 값을 지금까지의 최대합으로 업데이트 한다. + # - 현재 노드가 root인 subtree의 값이 최대일 수 있기 때문에 + self.res = max( + self.res, + left_total + right_total + node.val + ) + + # 위로 올릴 때는 왼쪽 노드와 오른쪽 노드 최대합 중에 + # 더 큰 값을 현재 노드 value와 더해서 올려준다. + return max(left_total, right_total) + node.val + + postorder(root) + return self.res From ba870029b2dc4bad297baf58108460f729631513 Mon Sep 17 00:00:00 2001 From: Yunyoung Chung Date: Fri, 15 May 2026 12:06:26 +0900 Subject: [PATCH 6/6] [7th batch] week 1 - top k frequent elements --- top-k-frequent-elements/liza0525.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 top-k-frequent-elements/liza0525.py diff --git a/top-k-frequent-elements/liza0525.py b/top-k-frequent-elements/liza0525.py new file mode 100644 index 0000000000..7b0342a538 --- /dev/null +++ b/top-k-frequent-elements/liza0525.py @@ -0,0 +1,23 @@ +from collections import defaultdict + +# 7기 풀이 +# 시간 복잡도: O(n log n) +# - sorting 로직으로 인해 n log n만큼(n: nums의 길이)의 시간 소요 +# 공간 복잡도: O(n) +# - nums 내에 distinct 요소의 개수만큼 count_map으로 공간 소요 +# - 최대 값: distinct요소 개수가 nums의 길이 값(n)과 동일할 때 +class Solution: + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + count_map = defaultdict(int) + + # 각 요소(num)의 개수를 저장 + for num in nums: + count_map[num] += 1 + + # count 기준으로 내림차순 정렬한 수 k만큼 list를 잘라준다. + return [ + num for num, _ in sorted( + [(num, count) for num, count in count_map.items()], + key=lambda x: -x[1] + ) + ][:k]