检查是否区域内所有整数都被覆盖
难度:
标签:
题目描述
You are given a 2D integer array ranges
and two integers left
and right
. Each ranges[i] = [starti, endi]
represents an inclusive interval between starti
and endi
.
Return true
if each integer in the inclusive range [left, right]
is covered by at least one interval in ranges
. Return false
otherwise.
An integer x
is covered by an interval ranges[i] = [starti, endi]
if starti <= x <= endi
.
Example 1:
Input: ranges = [[1,2],[3,4],[5,6]], left = 2, right = 5 Output: true Explanation: Every integer between 2 and 5 is covered: - 2 is covered by the first range. - 3 and 4 are covered by the second range. - 5 is covered by the third range.
Example 2:
Input: ranges = [[1,10],[10,20]], left = 21, right = 21 Output: false Explanation: 21 is not covered by any range.
Constraints:
1 <= ranges.length <= 50
1 <= starti <= endi <= 50
1 <= left <= right <= 50
代码结果
运行时间: 24 ms, 内存: 16.0 MB
/*
* 思路:
* 1. 使用流(Stream)来处理区间。
* 2. 使用一个 HashSet 来存储所有被覆盖的整数。
* 3. 遍历 left 到 right 的每个整数,检查它们是否都在 HashSet 中。
*/
import java.util.HashSet;
import java.util.Set;
import java.util.stream.IntStream;
public class Solution {
public boolean isCovered(int[][] ranges, int left, int right) {
Set<Integer> covered = new HashSet<>();
for (int[] range : ranges) {
IntStream.rangeClosed(range[0], range[1]).forEach(covered::add);
}
return IntStream.rangeClosed(left, right).allMatch(covered::contains);
}
}
解释
方法:
该题解采用了标记数组的方法来解决问题。首先,创建一个长度为51的数组tmp(考虑到题目中的整数范围可能从1到50),用于记录特定整数是否被覆盖。对于每个区间[starti, endi],遍历该区间中的所有整数,并将对应的tmp数组中的值设为1,表示该整数已被覆盖。接着,遍历从left到right的所有整数,检查这些整数是否都在tmp数组中被标记为1(即被覆盖)。如果存在未被覆盖的整数,则直接返回False。如果所有整数都被覆盖,则返回True。
时间复杂度:
O(N+M)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么选择使用长度为51的数组tmp来记录覆盖状态而不是其他数据结构,如哈希表或集合?
▷🦆
在创建tmp数组时,为何初始化长度为51,而不是基于left和right的值来调整数组的大小?
▷🦆
如果ranges中的区间非常大,比如[starti, endi]覆盖了大量不在[left, right]区间内的整数,这种方法的空间效率如何?
▷