diff --git a/insert-interval/bhyun-kim.py b/insert-interval/bhyun-kim.py new file mode 100644 index 000000000..2b8ff9606 --- /dev/null +++ b/insert-interval/bhyun-kim.py @@ -0,0 +1,45 @@ +""" +57. Insert Interval +https://leetcode.com/problems/insert-interval/ + +Solution: + To solve this problem, we can follow the following steps: + 1. Create an empty list called result to store the final intervals. + 2. Initialize a variable i to 0 to iterate through the intervals. + 3. Iterate through the intervals and add all intervals ending before the new interval starts to the result list. + +Time Complexity: O(n) + - + +""" + + +from typing import List + + +class Solution: + def insert( + self, intervals: List[List[int]], newInterval: List[int] + ) -> List[List[int]]: + result = [] + i = 0 + n = len(intervals) + + # Add all intervals ending before the new interval starts + while i < n and intervals[i][1] < newInterval[0]: + result.append(intervals[i]) + i += 1 + + # Merge all overlapping intervals with the new interval + while i < n and intervals[i][0] <= newInterval[1]: + newInterval[0] = min(newInterval[0], intervals[i][0]) + newInterval[1] = max(newInterval[1], intervals[i][1]) + i += 1 + result.append(newInterval) + + # Add all intervals starting after the new interval ends + while i < n: + result.append(intervals[i]) + i += 1 + + return result diff --git a/meeting-rooms-ii/bhyun-kim.py b/meeting-rooms-ii/bhyun-kim.py new file mode 100644 index 000000000..0067f6b68 --- /dev/null +++ b/meeting-rooms-ii/bhyun-kim.py @@ -0,0 +1,46 @@ +""" +253. Meeting Rooms II +https://leetcode.com/problems/meeting-rooms-ii/ + +Solution: + To solve this problem, we can follow the following steps: + 1. Sort the intervals based on their start times. + 2. Initialize a list called room_times with a dummy interval. + 3. Iterate through the intervals and assign each meeting to a room. + 4. If a meeting can be assigned to an existing room, update the room's end time. + 5. If a meeting cannot be assigned to an existing room, add a new room. + 6. Return the number of rooms used. + +Time Complexity: O(nlogn) + - Sorting the intervals takes O(nlogn) time. + - Iterating through the intervals takes O(n) time. + - Overall, the time complexity is O(nlogn). + +Space Complexity: O(n) + - We are using a list to store the room times. +""" + +from typing import List + + +class Solution: + def minMeetingRooms(self, intervals: List[List[int]]) -> int: + intervals = sorted(intervals) + room_times = [[-1, -1]] + meet_idx = 0 + + while meet_idx < len(intervals): + m_t = intervals[meet_idx] + found_room = False + for i in range(len(room_times)): + r_t = room_times[i] + if m_t[0] >= r_t[1]: + room_times[i] = m_t + found_room = True + break + + if not found_room: + room_times.append(m_t) + meet_idx += 1 + + return len(room_times) diff --git a/merge-intervals/bhyun-kim.py b/merge-intervals/bhyun-kim.py new file mode 100644 index 000000000..84051db33 --- /dev/null +++ b/merge-intervals/bhyun-kim.py @@ -0,0 +1,40 @@ +""" +56. Merge Intervals +https://leetcode.com/problems/merge-intervals/ + +Solution: + To solve this problem, we can follow the following steps: + 1. Sort the intervals by their start times. + 2. Initialize an empty list called merged to store the final merged intervals. + 3. Iterate through the sorted intervals and merge the current interval with the previous interval if there is an overlap. + +Time Complexity: O(nlogn) + - Sorting the intervals takes O(nlogn) time. + - Merging the intervals takes O(n) time. + - Overall, the time complexity is O(nlogn). + +Space Complexity: O(n) + - The space complexity is O(n) to store the merged intervals. +""" + +from typing import List + + +class Solution: + def merge(self, intervals: List[List[int]]) -> List[List[int]]: + if not intervals: + return [] + + # Sort intervals by their start times + intervals.sort(key=lambda x: x[0]) + + merged = [] + for interval in intervals: + # if the list of merged intervals is empty or if the current interval does not overlap with the previous + if not merged or merged[-1][1] < interval[0]: + merged.append(interval) + else: + # there is an overlap, so we merge the current and previous intervals + merged[-1][1] = max(merged[-1][1], interval[1]) + + return merged diff --git a/non-overlapping-intervals/bhyun-kim.py b/non-overlapping-intervals/bhyun-kim.py new file mode 100644 index 000000000..8cf87dac3 --- /dev/null +++ b/non-overlapping-intervals/bhyun-kim.py @@ -0,0 +1,42 @@ +""" +435. Non-overlapping Intervals +https://leetcode.com/problems/non-overlapping-intervals/ + +Solution: + To solve this problem, we can follow the following steps: + 1. Sort the intervals based on their end times. + 2. Initialize the end time of the last added interval. + 3. Iterate through the intervals and add non-overlapping intervals to the count. + 4. The number of intervals to remove is the total number minus the count of non-overlapping intervals. + +Time Complexity: O(nlogn) + - Sorting the intervals takes O(nlogn) time. + - Iterating through the intervals takes O(n) time. + - Overall, the time complexity is O(nlogn). + +Space Complexity: O(1) + - We are using a constant amount of space to store the end time of the last added interval. +""" + +from typing import List + + +class Solution: + def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int: + if not intervals: + return 0 + + # Sort intervals based on end times + intervals.sort(key=lambda x: x[1]) + + # Initialize the end time of the last added interval + end = intervals[0][1] + count = 1 + + for i in range(1, len(intervals)): + if intervals[i][0] >= end: + count += 1 + end = intervals[i][1] + + # The number of intervals to remove is the total number minus the count of non-overlapping intervals + return len(intervals) - count diff --git a/rotate-image/bhyun-kim.py b/rotate-image/bhyun-kim.py new file mode 100644 index 000000000..de8d663ff --- /dev/null +++ b/rotate-image/bhyun-kim.py @@ -0,0 +1,48 @@ +""" +48. Rotate Image +https://leetcode.com/problems/rotate-image/ + +Solution: + To solve this problem, we can follow the following steps: + 1. Process layers from the outermost to the innermost. + 2. For each layer, iterate through the elements in the layer. + 3. Swap the elements in the layer in a clockwise direction. + 4. Repeat the process for all layers. + +Time Complexity: O(n^2) + - We need to process all elements in the matrix. + - The time complexity is O(n^2). + +Space Complexity: O(1) + - We are rotating the matrix in place without using any extra space. +""" + +from typing import List + + +class Solution: + def rotate(self, matrix: List[List[int]]) -> None: + """ + Do not return anything, modify matrix in-place instead. + """ + n = len(matrix) + # Process layers from the outermost to the innermost + for layer in range(n // 2): + first = layer + last = n - layer - 1 + for i in range(first, last): + offset = i - first + # Save the top element + top = matrix[first][i] + + # Move left element to top + matrix[first][i] = matrix[last - offset][first] + + # Move bottom element to left + matrix[last - offset][first] = matrix[last][last - offset] + + # Move right element to bottom + matrix[last][last - offset] = matrix[i][last] + + # Assign top element to right + matrix[i][last] = top