From 367d4dafd6940614760a3815a8befc40315659c1 Mon Sep 17 00:00:00 2001 From: bhyun-kim Date: Thu, 16 May 2024 16:59:38 -0500 Subject: [PATCH] =?UTF-8?q?[bhyun-kim,=20=EA=B9=80=EB=B3=91=ED=98=84]=20So?= =?UTF-8?q?lution=20of=20Week=203=20Assignments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- climbing-stairs/bhyun-kim.py | 39 ++++++++++++ invert-binary-tree/bhyun-kim.py | 4 +- maximum-depth-of-binary-tree/bhyun-kim.py | 41 +++++++++++++ meeting-rooms/bhyun-kim.py | 55 +++++++++++++++++ same-tree/bhyun-kim.py | 43 +++++++++++++ subtree-of-another-tree/bhyun-kim.py | 75 +++++++++++++++++++++++ 6 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 climbing-stairs/bhyun-kim.py create mode 100644 maximum-depth-of-binary-tree/bhyun-kim.py create mode 100644 meeting-rooms/bhyun-kim.py create mode 100644 same-tree/bhyun-kim.py create mode 100644 subtree-of-another-tree/bhyun-kim.py diff --git a/climbing-stairs/bhyun-kim.py b/climbing-stairs/bhyun-kim.py new file mode 100644 index 000000000..67613f942 --- /dev/null +++ b/climbing-stairs/bhyun-kim.py @@ -0,0 +1,39 @@ +""" +70. Climbing Stairs +https://leetcode.com/problems/climbing-stairs/description/ + +Solution: + This is a combinatorial problem that allows duplicates. + We can use the formula for combinations to solve this problem. + Let's suppose that n is the number of steps, and k is the number of 2-steps. + Then, the number of ways to climb the stairs is n!/((n-2k)!k!). + We can iterate through all possible values of k, and calculate the number of ways to climb the stairs. + + 1. Create a dictionary to store the factorials of numbers from 0 to n. + 2. Calculate the factorials of numbers from 0 to n. + 3. Iterate through all possible values of k from 0 to n//2. + + +Time complexity: O(n) +Space complexity: O(n) +""" + +from collections import defaultdict + + +class Solution: + def climbStairs(self, n: int) -> int: + factorials = defaultdict(int) + factorials[0] = 1 + + fact = 1 + for i in range(1, n + 1): + fact = fact * i + factorials[i] = fact + + output = 0 + + for i in range(n // 2 + 1): + num_ways = factorials[n - i] / factorials[n - (i * 2)] / factorials[i] + output += num_ways + return int(output) diff --git a/invert-binary-tree/bhyun-kim.py b/invert-binary-tree/bhyun-kim.py index 0a7971a48..d977a9ef9 100644 --- a/invert-binary-tree/bhyun-kim.py +++ b/invert-binary-tree/bhyun-kim.py @@ -31,7 +31,9 @@ def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: has_right = hasattr(root, "right") if has_left and has_right: - root.left, root.right = self.invertTree(root.right), self.invertTree(root.left) + root.left, root.right = self.invertTree(root.right), self.invertTree( + root.left + ) elif has_left: root.left, root.right = None, self.invertTree(root.left) elif has_right: diff --git a/maximum-depth-of-binary-tree/bhyun-kim.py b/maximum-depth-of-binary-tree/bhyun-kim.py new file mode 100644 index 000000000..3766bebdc --- /dev/null +++ b/maximum-depth-of-binary-tree/bhyun-kim.py @@ -0,0 +1,41 @@ +""" +104. Maximum Depth of Binary Tree +https://leetcode.com/problems/maximum-depth-of-binary-tree/ + +Solution: + This is a recursive problem that requires traversing the binary tree. + We can use a recursive function to traverse the binary tree and calculate the depth. + The depth of the binary tree is the maximum of the depth of the left and right subtrees. + We can calculate the depth of the left and right subtrees recursively. + The base case is when the root is None, in which case the depth is 0. + + 1. Calculate the depth of the left subtree. + 2. Calculate the depth of the right subtree. + 3. Return the maximum of the depth of the left and right subtrees plus 1. + +Time complexity: O(n) +Space complexity: O(n) +""" + + +from typing import Optional + + +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: + max_dep_left = 0 + max_dep_right = 0 + + if hasattr(root, "left"): + max_dep_left = 1 + self.maxDepth(root.left) + if hasattr(root, "right"): + max_dep_right = 1 + self.maxDepth(root.right) + + return max(max_dep_left, max_dep_right) diff --git a/meeting-rooms/bhyun-kim.py b/meeting-rooms/bhyun-kim.py new file mode 100644 index 000000000..88b8518ea --- /dev/null +++ b/meeting-rooms/bhyun-kim.py @@ -0,0 +1,55 @@ +""" +252. Meeting Rooms +https://leetcode.com/problems/meeting-rooms/ + +Solution: + This is a sorting problem that requires comparing intervals. + We can sort the intervals by the start time. + Then, we can iterate through the sorted intervals and check if the end time of the current interval is greater than the start time of the next interval. + If it is, then we return False. + Otherwise, we return True. + + 1. Sort the intervals by the start time. + 2. Iterate through the sorted intervals. + 3. Check if the end time of the current interval is greater than the start time of the next interval. + + +Time complexity: O(nlogn) +Space complexity: O(1) + +Discarded solution: + This solution uses a hash table to store the time table of the intervals. + We iterate through the intervals and check if there is any overlap in the time table. + + 1. Create a hash table to store the time table of the intervals. + 2. Iterate through the intervals. + 3. Check if there is any overlap in the time table. + 4. Return False if there is an overlap, otherwise return True. + +Time complexity: O(n^2) +Space complexity: O(n) + +class Solution: + def canAttendMeetings(self, intervals: List[List[int]]) -> bool: + + time_table = defaultdict(int) + for itrv in intervals: + for i in range(itrv[0], itrv[1]): + if time_table[i] == 0: + time_table[i] += 1 + else: + return False + return True +""" + + +from typing import List + + +class Solution: + def canAttendMeetings(self, intervals: List[List[int]]) -> bool: + intervals.sort() + for i in range(len(intervals) - 1): + if intervals[i][1] > intervals[i + 1][0]: + return False + return True diff --git a/same-tree/bhyun-kim.py b/same-tree/bhyun-kim.py new file mode 100644 index 000000000..4bff4667d --- /dev/null +++ b/same-tree/bhyun-kim.py @@ -0,0 +1,43 @@ +""" +100. Same Tree +https://leetcode.com/problems/same-tree/description/ + +Solution: + This is a recursive problem that requires comparing two binary trees. + We can use a recursive function to compare the values of the nodes in the two binary trees. + If the values of the nodes are equal, we can compare the left and right subtrees recursively. + The base case is when both nodes are None, in which case we return True. + + 1. Check if the values of the nodes are equal. + 2. Compare the left and right subtrees recursively. + 3. Return True if the values of the nodes are equal and the left and right subtrees are equal, otherwise return False. +""" + + +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 p == q == None: + return True + + if hasattr(p, "val") and hasattr(q, "val"): + if p.val != q.val: + return False + + left_same = self.isSameTree(p.left, q.left) + right_same = self.isSameTree(p.right, q.right) + + return left_same == right_same == True + + else: + return False diff --git a/subtree-of-another-tree/bhyun-kim.py b/subtree-of-another-tree/bhyun-kim.py new file mode 100644 index 000000000..5aa654fc4 --- /dev/null +++ b/subtree-of-another-tree/bhyun-kim.py @@ -0,0 +1,75 @@ +""" +572. Subtree of Another Tree +https://leetcode.com/problems/subtree-of-another-tree/description/ + +Solution: + This solution uses a depth-first search to find the subtree in the tree. + We can use a recursive function to traverse the tree and compare the nodes. + If the given node is identical to the subtree, we return True. + Otherwise, we go to the left and right subtrees recursively. + In this solution we use two helper functions: depth_first_search and is_identical. + + Depth-first search: + 1. Check if the root is None. + 2. Check if the root is identical to the subtree. + 3. Go to the left and right subtrees recursively. + + Is identical: + 1. Check if both nodes are None. + 2. Check if one of the nodes is None. + 3. Check if the values of the nodes are equal. + 4. Compare the left and right subtrees recursively. + + +Complexity analysis: + Time complexity: O(n*m) + Where n is the number of nodes in the tree and m is the number of nodes in the subtree. + The depth-first search function has a time complexity of O(n). + The is_identical function has a time complexity of O(m). + Therefore, the overall time complexity is O(n*m). + + Space complexity: O(n) + Where n is the number of nodes in the tree. + The space complexity is O(n) because of the recursive calls to the depth_first_search function. +""" + + +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 isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool: + def depth_first_search(root): + if root is None: + return False + + if is_identical(root, subRoot): + return True + + return depth_first_search(root.left) or depth_first_search(root.right) + + def is_identical(root1, root2): + if root1 is None and root2 is None: + return True + if root1 is not None and root2 is None: + return False + if root1 is None and root2 is not None: + return False + if root1.val == root2.val: + return ( + is_identical(root1.left, root2.left) + == is_identical(root1.right, root2.right) + == True + ) + else: + return False + + return depth_first_search(root)