leetcode
leetcode 2051 ~ 2100
将区间分为最少组数

将区间分为最少组数

难度:

标签:

题目描述

代码结果

运行时间: 216 ms, 内存: 43.6 MB


/*
 * Problem Statement:
 * Given a list of intervals, group them such that no two intervals in the same group overlap.
 * Find the minimum number of groups required.
 * 
 * Approach:
 * 1. Sort intervals using Java Streams.
 * 2. Utilize a PriorityQueue to manage group end times.
 * 3. For each interval, if it doesn't overlap with the earliest ending interval, reuse that group.
 * 4. Otherwise, create a new group.
 */
import java.util.*;
import java.util.stream.Collectors;

public class IntervalPartitionStream {
    public int minGroups(int[][] intervals) {
        // Sort intervals using streams
        List<int[]> sortedIntervals = Arrays.stream(intervals)
            .sorted((a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0])
            .collect(Collectors.toList());
        // PriorityQueue to manage group end times
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        for (int[] interval : sortedIntervals) {
            if (!pq.isEmpty() && pq.peek() < interval[0]) {
                pq.poll();
            }
            pq.add(interval[1]);
        }
        return pq.size();
    }
}

解释

方法:

本题解的思路是利用贪心算法和最小堆(优先队列)来求解。首先,将所有区间按照起始位置进行排序。排序之后,遍历每个区间,并使用一个最小堆来维护当前活跃的区间组的结束时间。对于每个区间,如果它的起始时间大于堆顶的区间结束时间(表示该区间可以加入到当前最早结束的区间组中),则用当前区间的结束时间替换堆顶元素(更新该组的结束时间)。如果不满足上述条件(表示当前区间与所有活跃组都有重叠),则新开一个区间组,并将当前区间的结束时间加入堆中。最终,堆的大小即为所需的最少区间组数。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
在何种情形下,当前区间无法加入任何一个已有的区间组而必须新开一个区间组?
当当前区间的起始时间小于或等于最小堆(优先队列)中的堆顶元素时,即当前区间的起始时间小于或等于所有活跃区间组中最早结束的区间组的结束时间时,说明当前区间与所有已有的区间组都至少有一个共同点或重叠部分,因此无法加入任何一个已有的区间组。在这种情况下,必须新开一个区间组,并将当前区间的结束时间加入到最小堆中。

相关问题