LeetCode Entry
2406. Divide Intervals Into Minimum Number of Groups
Count non-intersecting groups of intervals
2406. Divide Intervals Into Minimum Number of Groups medium
blog post
substack
youtube

Join me on Telegram
https://t.me/leetcode_daily_unstoppable/766
Problem TLDR
Count non-intersecting groups of intervals #medium #heap #sorting
Intuition
Let’s observe the intervals’ properties:
// 5,10 6,8 1,5 2,3 1,10 n=5
//
// 1 2 3 4 5 6 7 8 9 10
// . . . . . . 5->take min g3(10)
// . . . 6->take min g1(5)
// . . . . . g1(5)
// . . g3(3)
// . . . . . . . . . . g2(10)
If we use sweep line algorithm, then we should peek the first non-intersecting group or add another group. To track the groups, let’s maintain a heap with ends of each group.
Another way to solve this is to notice some observation: groups count is the maximum intersecting intervals count (but it should be proved somehow, it is just works magically)
Approach
- to sweep line to work, we should sort for both
endsandstartsto be in increasing order - for the second way, we can use counting sorting
Complexity
-
Time complexity: \(O(n)\) or O(nlog(n))
-
Space complexity: \(O(m)\) or O(n)
Code
fun minGroups(intervals: Array<IntArray>): Int {
intervals.sortWith(compareBy({ it[0] }, { it[1] }))
val ends = PriorityQueue<Int>()
for ((a, b) in intervals) {
if (ends.size > 0 && a > ends.peek()) ends.poll()
ends += b
}
return ends.size
}
pub fn min_groups(intervals: Vec<Vec<i32>>) -> i32 {
let (mut ends, mut curr) = (vec![0; 1_000_002], 0);
for iv in intervals {
ends[iv[0] as usize] += 1; ends[1 + iv[1] as usize] -= 1; }
ends.iter().map(|e| { curr += e; curr }).max().unwrap()
}
int minGroups(vector<vector<int>>& intervals) {
int ends[1000002] = {}, curr = 0, res = 0;
for (auto iv: intervals) ends[iv[0]]++, ends[iv[1] + 1]--;
for (int e: ends) res = max(res, curr += e);
return res;
}