You are given a 2D integer array intervals
where intervals[i] = [lefti, righti]
represents the inclusive interval [lefti, righti]
.
You have to divide the intervals into one or more groups such that each interval is in exactly one group, and no two intervals that are in the same group intersect each other.
Return the minimum number of groups you need to make.
Two intervals intersect if there is at least one common number between them. For example, the intervals [1, 5]
and [5, 8]
intersect.
Example 1:
Input: intervals = [[5,10],[6,8],[1,5],[2,3],[1,10]] Output: 3 Explanation: We can divide the intervals into the following groups: - Group 1: [1, 5], [6, 8]. - Group 2: [2, 3], [5, 10]. - Group 3: [1, 10]. It can be proven that it is not possible to divide the intervals into fewer than 3 groups.
Example 2:
Input: intervals = [[1,3],[5,6],[8,10],[11,13]] Output: 1 Explanation: None of the intervals overlap, so we can put all of them in one group.
Constraints:
1 <= intervals.length <= 105
intervals[i].length == 2
1 <= lefti <= righti <= 106
This problem asks to find the minimum number of groups needed to divide a set of intervals such that no two intervals within the same group overlap. The optimal approach leverages a greedy strategy combined with a priority queue (min-heap).
Algorithm:
Sort: Sort the intervals by their starting times (left endpoints). This ensures we process intervals in increasing order of their start times.
Priority Queue (Min-Heap): Use a min-heap data structure to track the ending times (right endpoints) of the intervals currently assigned to different groups. The min-heap's minimum element always represents the earliest ending time among all active groups.
Iterate and Assign: Iterate through the sorted intervals:
Result: Finally, the size of the min-heap represents the minimum number of groups required. Each element in the heap corresponds to a group, and its value is the right endpoint of the last interval added to that group.
Time Complexity: O(N log N) - dominated by sorting the intervals. The heap operations (insertion, deletion, peek) take logarithmic time.
Space Complexity: O(N) - proportional to the maximum size of the heap (worst case, all intervals might end up in separate groups).
Code Examples (Python):
import heapq
def minGroups(intervals):
intervals.sort() # Sort by start times
min_heap = [] # Min-heap to track ending times of groups
for start, end in intervals:
if min_heap and min_heap[0] <= start: # Check for overlap
heapq.heapreplace(min_heap, end) # Replace the earliest ending time
else:
heapq.heappush(min_heap, end) # Create a new group
return len(min_heap) # Number of groups is the heap size
#Example Usage
intervals = [[5,10],[6,8],[1,5],[2,3],[1,10]]
result = minGroups(intervals)
print(f"Minimum Number of Groups: {result}") # Output: 3
intervals = [[1,3],[5,6],[8,10],[11,13]]
result = minGroups(intervals)
print(f"Minimum Number of Groups: {result}") # Output: 1
The code in other languages (Java, C++, Go, TypeScript) would follow a very similar structure, utilizing their respective sorting and priority queue implementations. The core logic remains the same, making it efficient and effective for solving the problem.