leetcode
leetcode 2351 ~ 2400
寻找最大长度的未覆盖区间

寻找最大长度的未覆盖区间

难度:

标签:

题目描述

代码结果

运行时间: 1252 ms, 内存: 81.2 MB


/*
题目思路:
1. 给定一个范围 [1, n] 和一个区间列表 intervals,其中每个区间 intervals[i] = [a, b]。
2. 任务是找出这些区间列表中未覆盖的最大连续子区间的长度。
3. 首先将区间列表按照起点进行排序,然后合并重叠的区间。
4. 遍历合并后的区间,计算相邻区间之间的差值,即未覆盖区间的长度。
5. 返回这些未覆盖区间长度的最大值。
*/

import java.util.*;
import java.util.stream.*;

public class Solution {
    public int findMaxUncoveredInterval(int n, int[][] intervals) {
        if (intervals == null || intervals.length == 0) {
            return n;
        }

        List<int[]> merged = Arrays.stream(intervals)
            .sorted((a, b) -> Integer.compare(a[0], b[0]))
            .collect(Collectors.toList());

        int[] current = merged.get(0);
        List<int[]> mergedIntervals = new ArrayList<>();
        for (int i = 1; i < merged.size(); i++) {
            if (current[1] >= merged.get(i)[0]) {
                current[1] = Math.max(current[1], merged.get(i)[1]);
            } else {
                mergedIntervals.add(current);
                current = merged.get(i);
            }
        }
        mergedIntervals.add(current);

        int maxUncovered = 0;
        int prevEnd = 0;
        for (int[] interval : mergedIntervals) {
            maxUncovered = Math.max(maxUncovered, interval[0] - prevEnd - 1);
            prevEnd = interval[1];
        }
        maxUncovered = Math.max(maxUncovered, n - prevEnd);

        return maxUncovered;
    }
}

解释

方法:

解题思路是首先对给定的区间按照起始位置进行排序,然后遍历排序后的区间列表,找出每个区间之间未被覆盖的部分。通过维持一个变量 `start` 来标记当前未覆盖区间的起始点。在遍历每一个区间时,如果 `start` 小于当前区间的起始位置,说明存在一个未覆盖的区间,将其加入结果列表。随后更新 `start` 的值为当前区间结束位置加一。最后,还需要检查在最后一个区间结束后是否还有未覆盖的区间直到 n。

时间复杂度:

O(m log m)

空间复杂度:

O(m)

代码细节讲解

🦆
为什么在对区间进行排序时,只按照起始位置进行排序而不考虑结束位置?
对区间按起始位置进行排序的目的是为了确定每个区间开始的准确顺序,从而便于找出它们之间的未覆盖区间。如果在排序中同时考虑结束位置,可能会导致处理复杂化,因为即使一个区间早于另一个区间结束,但如果它开始得更晚,仍可能覆盖前一个区间的部分或全部。因此,首先按起始位置排序可以简化逻辑,确保我们能从左至右检查每个潜在的未覆盖区间。
🦆
在更新`start`变量为当前区间结束位置加一时,如果下一个区间的起始位置与当前区间的结束位置相同怎么处理?
在这种情况下,下一个区间的起始位置恰好是当前区间结束位置的下一个位置,因此没有留下未覆盖的空间。`start`变量已经更新为当前区间的结束位置加一,这意味着它正好等于下一个区间的起始位置。因此,这种情况下不会添加新的未覆盖区间,算法会继续检查之后的区间。
🦆
算法中如何确保在所有区间处理完成后,能够正确检测并添加最后一个未覆盖的区间直到n?
算法通过在遍历完所有给定区间后,检查`start`变量与`n`的关系来确保此点。如果`start`小于`n`,这意味着从`start`到`n-1`之间的区间未被覆盖,因此这一部分会被添加到结果列表中作为最后一个未覆盖区间。这样可以确保算法不遗漏任何位于最后一个给定区间之后且直到`n-1`的未覆盖区间。
🦆
函数参数中的`n`具体代表什么?在题目和解答中对它的使用是否有详细的解释?
`n`代表考虑的区间内的最大边界值,即区间从0开始,直到`n-1`。在题解中,`n`用来标识在所有给定区间之后可能存在的未覆盖区间的结束位置。题解中通过检查在处理完所有给定区间之后`start`变量的值是否小于`n`,来确定是否还存在未覆盖区间,确保算法能覆盖从0到`n-1`的完整范围,这对理解题目范围和解题方法是至关重要的。

相关问题