Skip to content

[bhyun-kim, 김병현] Solution of Week 3 Assignments #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions climbing-stairs/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -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 >> 1) + 1):
num_ways = factorials[n - i] // factorials[n - (i * 2)] // factorials[i]
output += num_ways
return int(output)
4 changes: 3 additions & 1 deletion invert-binary-tree/bhyun-kim.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
41 changes: 41 additions & 0 deletions maximum-depth-of-binary-tree/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -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)
55 changes: 55 additions & 0 deletions meeting-rooms/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -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
43 changes: 43 additions & 0 deletions same-tree/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -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
76 changes: 76 additions & 0 deletions subtree-of-another-tree/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""
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(m+n)
Where n is the number of nodes in the tree and m is the number of nodes in the subtree.
The space complexity is O(m+n) because of the recursive calls to the depth_first_search function
and is_identical.
"""


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)