Skip to content

Commit be0e4fd

Browse files
authored
Merge pull request #142 from BrianLusina/feat/algorithms-intervals-can-attend-meetings
feat(algorithms, intervals): can attend meetings
2 parents e983f02 + 58a6208 commit be0e4fd

File tree

4 files changed

+114
-0
lines changed

4 files changed

+114
-0
lines changed

DIRECTORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@
131131
* [Decoding](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/huffman/decoding.py)
132132
* [Encoding](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/huffman/encoding.py)
133133
* Intervals
134+
* Can Attend Meetings
135+
* [Test Can Attend Meetings](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/intervals/can_attend_meetings/test_can_attend_meetings.py)
134136
* Car Pooling
135137
* [Test Car Pooling](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/intervals/car_pooling/test_car_pooling.py)
136138
* Count Days
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Can Attend Meetings
2+
3+
Write a function to check if a person can attend all the meetings scheduled without any time conflicts. Given an array
4+
intervals, where each element [s1, e1] represents a meeting starting at time s1 and ending at time e1, determine if
5+
there are any overlapping meetings. If there is no overlap between any meetings, return true; otherwise, return false.
6+
7+
Note that meetings ending and starting at the same time, such as (0,5) and (5,10), do not conflict.
8+
9+
Examples:
10+
11+
```text
12+
Input: intervals = [(1,5),(3,9),(6,8)]
13+
Output: False
14+
15+
Explanation: The meetings (1,5) and (3,9) overlap.
16+
```
17+
18+
```text
19+
Input: intervals = [(10,12),(6,9),(13,15)]
20+
Output: True
21+
22+
Explanation: There are no overlapping meetings, so the person can attend all.
23+
```
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from typing import List
2+
3+
4+
def can_attend_meetings(intervals: List[List[int]]) -> bool:
5+
"""
6+
Checks if an employee can attend all meetings given a list of intervals representing the start and end times of each
7+
meeting.
8+
9+
A person can attend all meetings if and only if none of the meetings overlap. By sorting the intervals by start time,
10+
we can easily check if any two consecutive intervals overlap.
11+
12+
We iterate over each interval, beginning with the second interval in the sorted list. We compare the start time of
13+
the current interval with the end time of the previous interval. If the start time of the current interval is less
14+
than the end time of the previous interval, then the two intervals overlap and the person cannot attend both meetings,
15+
so we return false.
16+
17+
Otherwise, the person can attend both meetings, and we continue to the next interval. If we reach the end of the
18+
list without finding any overlapping intervals, then the person can attend all meetings, and we return true.
19+
20+
Complexity Analysis
21+
22+
Time Complexity: O(n * logn) where n is the number of intervals. The time complexity is dominated by the sorting step.
23+
24+
Space Complexity:
25+
26+
Since we are sorting the intervals and creating a new sorted_intervals variable that has the sorted intervals by time
27+
the space incurred is O(n). However, if sorting in place, then the space cost becomes O(1) and in that case no extra
28+
extra space would be used beyond a few variables.
29+
30+
Args:
31+
intervals(list): list of intervals where each entry is a list containing the start and end time of a meeting
32+
Returns:
33+
bool: True if an employee can attend all meetings, false otherwise
34+
"""
35+
if len(intervals) == 0:
36+
return True
37+
38+
# Sort the intervals by start time first to enable easier iteration through the intervals. Meetings with similar
39+
# start times will be close to each other, allowing quick and early exit if they overlap.
40+
sorted_intervals = sorted(intervals, key=lambda x: x[0])
41+
42+
# Keep track of the last seen end time.
43+
# We initialize the first interval's end time to keep track of the last interval's end that we have seen so far
44+
last_end_time = sorted_intervals[0][1]
45+
46+
# We then iterate through the list checking if there is any overlaps
47+
# Start from the second interval in the list to check if it overlaps with the previous interval.
48+
for current_interval in sorted_intervals[1:]:
49+
# Get the start and end of the current interval
50+
current_start, current_end = current_interval
51+
52+
if current_start < last_end_time:
53+
# there is an overlap, we return here
54+
return False
55+
56+
# Otherwise, we update the last end time we have seen with this interval's end time
57+
last_end_time = current_end
58+
59+
# If no overlap is found, we return True
60+
return True
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import unittest
2+
from typing import List
3+
from parameterized import parameterized
4+
from algorithms.intervals.can_attend_meetings import can_attend_meetings
5+
6+
CAN_ATTEND_MEETINGS_TEST_CASES = [
7+
([[1, 5], [3, 9], [6, 8]], False),
8+
([[10, 12], [6, 9], [13, 15]], True),
9+
([[0, 30], [5, 10], [15, 20]], False),
10+
([[7, 10], [2, 4]], True),
11+
([[1, 2], [2, 3], [3, 4]], True),
12+
([[1, 2], [2, 3], [3, 4]], True),
13+
([[1, 3], [2, 4], [4, 6]], False),
14+
([[0, 1], [3, 5], [6, 7]], True),
15+
([[10, 20], [20, 30], [30, 40]], True),
16+
([[1, 5], [6, 10], [11, 15]], True),
17+
([[5, 10], [15, 20], [10, 15]], True),
18+
]
19+
20+
21+
class CanAttendMeetingsTestCase(unittest.TestCase):
22+
@parameterized.expand(CAN_ATTEND_MEETINGS_TEST_CASES)
23+
def test_can_attend_meetings(self, intervals: List[List[int]], expected: bool):
24+
actual = can_attend_meetings(intervals)
25+
self.assertEqual(expected, actual)
26+
27+
28+
if __name__ == "__main__":
29+
unittest.main()

0 commit comments

Comments
 (0)