From 39861659da9462929a650e876135a41fbdf2b7db Mon Sep 17 00:00:00 2001 From: EGON Date: Sat, 19 Oct 2024 19:56:21 +0900 Subject: [PATCH 1/7] feat: solve #226 with python --- invert-binary-tree/EGON.py | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 invert-binary-tree/EGON.py diff --git a/invert-binary-tree/EGON.py b/invert-binary-tree/EGON.py new file mode 100644 index 000000000..b49826895 --- /dev/null +++ b/invert-binary-tree/EGON.py @@ -0,0 +1,48 @@ +from typing import Optional +from unittest import TestCase, main + + +# 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 invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: + return self.solve_dfs(root) + + """ + Runtime: 0 ms (Beats 100.00%) + Time Complexity: O(n) + > 트리의 모든 node를 방문하므로 O(n) + + Memory: 16.53 MB (Beats 25.95%) + Space Complexity: O(n) + > stack의 최대 크기는 트리의 최장 경로를 이루는 node의 갯수이고, 최악의 경우 트리의 한 쪽으로 모든 node가 이어져있는 경우이므로 O(n), upper bound + """ + def solve_dfs(self, root: Optional[TreeNode]) -> Optional[TreeNode]: + if root is None: + return root + + stack = [root] + while stack: + curr_node = stack.pop() + curr_node.left, curr_node.right = curr_node.right, curr_node.left + if curr_node.left: + stack.append(curr_node.left) + if curr_node.right: + stack.append(curr_node.right) + + return root + + +class _LeetCodeTestCases(TestCase): + def test_1(self): + return + + +if __name__ == '__main__': + main() From 448a0362afcb4d0349dc4a0f34b57d8993eeb962 Mon Sep 17 00:00:00 2001 From: EGON Date: Sat, 19 Oct 2024 19:56:42 +0900 Subject: [PATCH 2/7] feat: solve #246 in python --- search-in-rotated-sorted-array/EGON.py | 67 ++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 search-in-rotated-sorted-array/EGON.py diff --git a/search-in-rotated-sorted-array/EGON.py b/search-in-rotated-sorted-array/EGON.py new file mode 100644 index 000000000..93a655a5b --- /dev/null +++ b/search-in-rotated-sorted-array/EGON.py @@ -0,0 +1,67 @@ +from typing import List +from unittest import TestCase, main + + +class Solution: + def search(self, nums: List[int], target: int) -> int: + return self.solve_binary_search(nums, target) + + """ + Runtime: 4 ms (Beats 100.00%) + Time Complexity: O(log n) + > nums를 이진탐색으로 조회하므로 O(log n) + + Memory: 17.03 MB (Beats 10.00%) + Space Complexity: O(1) + > index를 위한 정수형 변수만 사용하므로 O(1) + """ + def solve_binary_search(self, nums: List[int], target: int) -> int: + lo, hi = 0, len(nums) - 1 + while lo < hi: + mid = (lo + hi) // 2 + if nums[mid] == target: + return mid + + if nums[lo] <= nums[mid]: + if nums[lo] <= target <= nums[mid]: + hi = mid + else: + lo = mid + 1 + + else: + if nums[mid] <= target <= nums[hi]: + lo = mid + 1 + else: + hi = mid + + return lo if nums[lo] == target else -1 + + +class _LeetCodeTestCases(TestCase): + def test_1(self): + nums = [4,5,6,7,0,1,2] + target = 0 + output = 4 + self.assertEqual(Solution.search(Solution(), nums, target), output) + + def test_2(self): + nums = [4,5,6,7,0,1,2] + target = 3 + output = -1 + self.assertEqual(Solution.search(Solution(), nums, target), output) + + def test_3(self): + nums = [1] + target = 0 + output = -1 + self.assertEqual(Solution.search(Solution(), nums, target), output) + + def test_4(self): + nums = [3, 1] + target = 1 + output = 1 + self.assertEqual(Solution.search(Solution(), nums, target), output) + + +if __name__ == '__main__': + main() From 1b6b41d337c501c3d310df007c4392f0d3c223a1 Mon Sep 17 00:00:00 2001 From: EGON Date: Sat, 19 Oct 2024 19:56:51 +0900 Subject: [PATCH 3/7] feat: solve #261 in python --- course-schedule/EGON.py | 58 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 course-schedule/EGON.py diff --git a/course-schedule/EGON.py b/course-schedule/EGON.py new file mode 100644 index 000000000..dbaf45a4c --- /dev/null +++ b/course-schedule/EGON.py @@ -0,0 +1,58 @@ +from collections import deque +from typing import List +from unittest import TestCase, main + + +class Solution: + def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: + return self.solve_topological_sort(numCourses, prerequisites) + + """ + Runtime: 1 ms (Beats 100.00%) + Time Complexity: o(c + p) + - graph 및 rank 갱신에 prerequisites의 길이 p만큼 조회하는데 O(p) + - queue의 초기 노드 삽입에 numCourses만큼 조회하는데 O(c) + - queue에서 위상 정렬로 탐색하는데 모든 노드와 간선을 조회하는데 O(c + p) + > O(p) + O(c) + O(c + p) ~= o(c + p) + + Memory: 17.85 MB (Beats 99.94%) + Space Complexity: O(c) + - graph 변수 사용에 O(c) + - rank 변수 사용에 O(c) + - queue 변수 사용에서 최대 크기는 graph의 크기와 같으므로 O(c) + > O(c) + O(c) + O(c) ~= O(c) + """ + def solve_topological_sort(self, numCourses: int, prerequisites: List[List[int]]) -> bool: + graph = {i: [] for i in range(numCourses)} + rank = [0] * numCourses + for u, v in prerequisites: + graph[v].append(u) + rank[u] += 1 + + queue = deque() + for i in range(numCourses): + if rank[i] == 0: + queue.append(i) + + count = 0 + while queue: + node = queue.popleft() + count += 1 + for neighbor in graph[node]: + rank[neighbor] -= 1 + if rank[neighbor] == 0: + queue.append(neighbor) + + return count == numCourses + + +class _LeetCodeTestCases(TestCase): + def test_1(self): + numCourses = 5 + prerequisites = [[1,4],[2,4],[3,1],[3,2]] + output = True + self.assertEqual(Solution.canFinish(Solution(), numCourses, prerequisites), output) + + +if __name__ == '__main__': + main() From 0a669d548cf77385192bde1675a85326dd52c4ea Mon Sep 17 00:00:00 2001 From: EGON Date: Sat, 19 Oct 2024 19:56:59 +0900 Subject: [PATCH 4/7] feat: solve #276 in python --- jump-game/EGON.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 jump-game/EGON.py diff --git a/jump-game/EGON.py b/jump-game/EGON.py new file mode 100644 index 000000000..9a2e3c54b --- /dev/null +++ b/jump-game/EGON.py @@ -0,0 +1,43 @@ +from typing import List +from unittest import TestCase, main + + +class Solution: + def canJump(self, nums: List[int]) -> bool: + return self.solve_dp(nums) + + """ + Runtime: 5585 ms (Beats 5.91%) + Time Complexity: O(n * m) + - dp 배열 생성에 nums의 길이 n 만큼 조회하는데 O(n) + - 생성한 dp 배열을 조회하는데 O(n) + - dp[i]에서 점프하는 범위에 의해 * O(2 * m) + > O(n) + O(n) * O(2 * m) ~= O(n * m) + + Memory: 17.80 MB (Beats 46.08%) + Space Complexity: O(n) + > nums의 길이에 비례하는 dp 배열 하나만 사용, O(n) + """ + def solve_dp(self, nums: List[int]) -> bool: + dp = [True if i == 0 else False for i in range(len(nums))] + for i in range(len(nums)): + if dp[-1] is True: + return True + + if dp[i] is True: + for jump in range(-nums[i], nums[i] + 1): + if 0 <= i + jump < len(dp): + dp[i + jump] = True + + return dp[-1] + + +class _LeetCodeTestCases(TestCase): + def test_1(self): + nums = [2, 3, 1, 1, 4] + output = True + self.assertEqual(Solution.canJump(Solution(), nums), output) + + +if __name__ == '__main__': + main() From 50af8813361492ac8e8ee1b3259ca0446039c088 Mon Sep 17 00:00:00 2001 From: EGON Date: Sat, 19 Oct 2024 19:57:08 +0900 Subject: [PATCH 5/7] feat: solve #286 in python --- merge-k-sorted-lists/EGON.py | 55 ++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 merge-k-sorted-lists/EGON.py diff --git a/merge-k-sorted-lists/EGON.py b/merge-k-sorted-lists/EGON.py new file mode 100644 index 000000000..a4eaa9517 --- /dev/null +++ b/merge-k-sorted-lists/EGON.py @@ -0,0 +1,55 @@ +from heapq import heappush, heappop +from typing import List, Optional +from unittest import TestCase, main + + +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + +class Solution: + def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + return self.solve_priority_queue(lists) + + """ + Runtime: 7 ms (Beats 100.00%) + Time Complexity: O(n * m) + - lists의 길이 k만큼 조회에 O(k) + - 힙의 크기가 최대 k이므로, heappush에 * O(log k) + - heap의 크기는 최대 k이므로, + - heappop하는데 O(k * log k) + - heappush하는데 lists를 이루는 list를 이루는 모든 원소들의 총 갯수를 n이라 하면, O(n * log k) + > O(k * log k) + O(k * log k) + O(n * log k) ~= O(max(k, n) * log k) = O(n * log k) + + Memory: 19.44 MB (Beats 58.42%) + Space Complexity: O(k) + > heap의 크기는 lists의 길이 k에 비례하므로, O(k) + """ + def solve_priority_queue(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: + root = result = ListNode(None) + heap = [] + + for i in range(len(lists)): + if lists[i]: + heappush(heap, (lists[i].val, i, lists[i])) + + while heap: + node = heappop(heap) + _, idx, result.next = node + + result = result.next + if result.next: + heappush(heap, (result.next.val, idx, result.next)) + + return root.next + + +class _LeetCodeTestCases(TestCase): + def test_1(self): + self.assertEqual(True, True) + + +if __name__ == '__main__': + main() From ac155d9943f13586899af923af98e5de8bf455f3 Mon Sep 17 00:00:00 2001 From: EGON Date: Tue, 22 Oct 2024 00:41:35 +0900 Subject: [PATCH 6/7] update: optimize #276 time complexity --- jump-game/EGON.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jump-game/EGON.py b/jump-game/EGON.py index 9a2e3c54b..a09030f29 100644 --- a/jump-game/EGON.py +++ b/jump-game/EGON.py @@ -7,14 +7,14 @@ def canJump(self, nums: List[int]) -> bool: return self.solve_dp(nums) """ - Runtime: 5585 ms (Beats 5.91%) + Runtime: 3130 ms (Beats 11.42%) Time Complexity: O(n * m) - dp 배열 생성에 nums의 길이 n 만큼 조회하는데 O(n) - 생성한 dp 배열을 조회하는데 O(n) - dp[i]에서 점프하는 범위에 의해 * O(2 * m) > O(n) + O(n) * O(2 * m) ~= O(n * m) - Memory: 17.80 MB (Beats 46.08%) + Memory: 17.80 MB (Beats 72.54%) Space Complexity: O(n) > nums의 길이에 비례하는 dp 배열 하나만 사용, O(n) """ @@ -25,7 +25,7 @@ def solve_dp(self, nums: List[int]) -> bool: return True if dp[i] is True: - for jump in range(-nums[i], nums[i] + 1): + for jump in range(nums[i] + 1): if 0 <= i + jump < len(dp): dp[i + jump] = True From e9629f7c99bf3f4fed9b5095b635f50d2fee3b69 Mon Sep 17 00:00:00 2001 From: EGON Date: Tue, 22 Oct 2024 00:42:15 +0900 Subject: [PATCH 7/7] edit : correct #261 code comments --- course-schedule/EGON.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/course-schedule/EGON.py b/course-schedule/EGON.py index dbaf45a4c..9f1bd04fa 100644 --- a/course-schedule/EGON.py +++ b/course-schedule/EGON.py @@ -17,10 +17,10 @@ def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: Memory: 17.85 MB (Beats 99.94%) Space Complexity: O(c) - - graph 변수 사용에 O(c) + - graph 변수 사용에 O(c + p) - rank 변수 사용에 O(c) - queue 변수 사용에서 최대 크기는 graph의 크기와 같으므로 O(c) - > O(c) + O(c) + O(c) ~= O(c) + > O(c + p) + O(c) + O(c) ~= O(c + p) """ def solve_topological_sort(self, numCourses: int, prerequisites: List[List[int]]) -> bool: graph = {i: [] for i in range(numCourses)}