From eee41dea445695cd4638326b5ed3130a5d9e73b8 Mon Sep 17 00:00:00 2001 From: Lyla Date: Sun, 23 Feb 2025 22:27:50 -0500 Subject: [PATCH 1/5] solve last 1 --- graph-valid-tree/pmjuu.py | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 graph-valid-tree/pmjuu.py diff --git a/graph-valid-tree/pmjuu.py b/graph-valid-tree/pmjuu.py new file mode 100644 index 000000000..13f6d76fe --- /dev/null +++ b/graph-valid-tree/pmjuu.py @@ -0,0 +1,45 @@ +''' +노드의 개수를 n, 간선의 개수를 e 라고 할때, + +시간 복잡도: O(n + e) +- 그래프의 모든 노드와 간선을 방문하므로 O(n + e) + +공간 복잡도: O(n + e) +- 인접 리스트와 방문 배열을 저장하는 데 O(n + e)의 공간이 필요합니다. +''' +from typing import List + +class Solution: + def validTree(self, n: int, edges: List[List[int]]) -> bool: + graph = { i: [] for i in range(n) } + for u, v in edges: + graph[u].append(v) + graph[v].append(u) + + visited = set() + + def hasCycle(node, parent): + if node in visited: + return True + + visited.add(node) + + for neighbor in graph[node]: + if neighbor == parent: + continue # 부모 노드로 돌아가지 않기 + if hasCycle(neighbor, node): + return True + + return False + + # 0번 노드에서 DFS 시작 + if hasCycle(0, -1): + return False + + # 모든 노드가 방문되었는지 확인 (연결성 체크) + return len(visited) == n + +# Example +solution = Solution() +print(solution.validTree(5, [[0, 1], [0, 2], [0, 3], [1, 4]])) # Output: True +print(solution.validTree(5, [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]])) # Output: False From 938ea550ac777f512e75353e763cdfec1b3afab0 Mon Sep 17 00:00:00 2001 From: Lyla Date: Tue, 25 Feb 2025 13:17:20 -0500 Subject: [PATCH 2/5] solve 1 --- same-tree/pmjuu.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 same-tree/pmjuu.py diff --git a/same-tree/pmjuu.py b/same-tree/pmjuu.py new file mode 100644 index 000000000..37f183773 --- /dev/null +++ b/same-tree/pmjuu.py @@ -0,0 +1,21 @@ +''' +시간 복잡도: O(n) +공간 복잡도: O(n) +''' +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 isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool: + if not p and not q: + return True + if not p or not q: + return False + + return p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) From ae3bd32f550a5657ce1a4087c9c883c3d8ecf0d4 Mon Sep 17 00:00:00 2001 From: Lyla Date: Wed, 26 Feb 2025 08:48:26 -0500 Subject: [PATCH 3/5] solve 2 --- remove-nth-node-from-end-of-list/pmjuu.py | 60 +++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 remove-nth-node-from-end-of-list/pmjuu.py diff --git a/remove-nth-node-from-end-of-list/pmjuu.py b/remove-nth-node-from-end-of-list/pmjuu.py new file mode 100644 index 000000000..01cc33638 --- /dev/null +++ b/remove-nth-node-from-end-of-list/pmjuu.py @@ -0,0 +1,60 @@ +''' +시간 복잡도: O(n) +공간 복잡도: 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 removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]: + # 리스트 길이 계산 + length = 1 + current = head + while current.next: + length += 1 + current = current.next + + # 제거할 노드가 첫 번째(head)인 경우 + if n == length: + return head.next + + index = 0 + current = head + + # 제거 대상 노드 전까지 이동 + for _ in range(length - n - 1): + current = current.next + + # 제거 대상 노드 건너뛰기 + current.next = current.next.next + + return head + +# Two-Pointer +class Solution: + def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]: + first = second = head + + # 1. `first`를 n 만큼 이동 → `second`와의 간격 유지 + for _ in range(n): + first = first.next + + # 제거 대상이 첫번째 노드인 경우, next 반환 + if not first: + return head.next + + # 2. `first`가 끝까지 갈 때까지 `second`도 함께 이동 + while first.next: + first = first.next + second = second.next + + # 3. `second.next`가 가리키는 노드 제거 + second.next = second.next.next + + return head From 5e8615ba2203057dfb1627fd05cc14dd3a007c79 Mon Sep 17 00:00:00 2001 From: Lyla Date: Wed, 26 Feb 2025 14:53:40 -0500 Subject: [PATCH 4/5] solve 3 --- .../pmjuu.py | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 number-of-connected-components-in-an-undirected-graph/pmjuu.py diff --git a/number-of-connected-components-in-an-undirected-graph/pmjuu.py b/number-of-connected-components-in-an-undirected-graph/pmjuu.py new file mode 100644 index 000000000..a7607e6e5 --- /dev/null +++ b/number-of-connected-components-in-an-undirected-graph/pmjuu.py @@ -0,0 +1,50 @@ +''' +n: 노드 개수 / e: 간선 개수 +시간 복잡도: O(n + e) +공간 복잡도: O(n + e) +''' +from typing import List + +class Solution: + def count_components(self, n: int, edges: List[List[int]]) -> int: + graph = {i: [] for i in range(n)} + for u, v in edges: + graph[u].append(v) + graph[v].append(u) + + visited = set() + def dfs(node): + visited.add(node) + + for neighbor in graph[node]: + if neighbor not in visited: + dfs(neighbor) + + count = 0 + for node in graph: + if node not in visited: + count += 1 + dfs(node) + + return count + +# Test function +def test(): + solution = Solution() + test_cases = [ + (3, [[0, 1], [0, 2]], 1), + (6, [[0, 1], [1, 2], [2, 3], [4, 5]], 2), + (4, [[0, 1], [2, 3]], 2), + (1, [], 1), + (4, [[0, 1], [2, 3], [1, 2]], 1) + ] + + for i, (n, edges, expected) in enumerate(test_cases): + result = solution.count_components(n, edges) + print(f"Test case {i+1}: Input: n={n}, edges={edges} -> Output: {result}, Expected: {expected}") + if result != expected: + print(f"# Test case {i+1} failed: expected {expected}, got {result}") + print("\n") + +# Run tests +test() From 6f8065e754c1fae19cde485888a03f59c164bea4 Mon Sep 17 00:00:00 2001 From: Lyla Date: Thu, 27 Feb 2025 16:35:29 -0500 Subject: [PATCH 5/5] solve 4 --- non-overlapping-intervals/pmjuu.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 non-overlapping-intervals/pmjuu.py diff --git a/non-overlapping-intervals/pmjuu.py b/non-overlapping-intervals/pmjuu.py new file mode 100644 index 000000000..5d2b969c1 --- /dev/null +++ b/non-overlapping-intervals/pmjuu.py @@ -0,0 +1,22 @@ +''' +시간 복잡도: O(n log n) +공간 복잡도: O(1) +''' +from typing import List + + +class Solution: + def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int: + intervals.sort() + count = 0 + iter_intervals = iter(intervals) + prev_end = next(iter_intervals)[1] + + for start, end in iter_intervals: + if prev_end > start: + count += 1 + prev_end = min(prev_end, end) + else: + prev_end = end + + return count