You are given a list of ranges, where each range is represented as a two-element array [start, end]
and covers all the integers from start
to end
(inclusive). You are also given two integers, left
and right
. The task is to determine whether every integer in the inclusive range [left, right]
is covered by at least one of the given ranges.
left
and right
(inclusive).True
if all integers in [left, right]
are covered; otherwise, return False
.
The naive or brute-force approach is to check, for every integer between left
and right
, whether it is included in at least one of the ranges. This means iterating over each integer in the target interval and then checking all ranges for coverage. While this works for small inputs, it becomes inefficient if the intervals or the number of ranges are large.
To optimize, we can pre-process the ranges to quickly determine if a number is covered. One way is to use an array to mark all covered numbers, or employ a prefix sum (difference array) technique to efficiently record and query coverage. This reduces repeated checks and speeds up the solution, especially for larger input sizes.
We'll use a difference array (also known as a prefix sum array) to efficiently keep track of which numbers are covered by the ranges. Here’s how the approach works step by step:
covered
) large enough to include all possible numbers up to 50 (since constraints state numbers are between 1 and 50).[start, end]
, increment covered[start]
by 1 and decrement covered[end + 1]
by 1.covered
array and for each index, add the previous value to the current value. This gives the total number of times each integer is covered up to that point.left
to right
, check if its coverage count is at least 1. If any number is not covered, return False
.True
.This method is efficient because each range is processed only once, and the coverage for each number is determined in constant time using the prefix sum.
Input: ranges = [[1,2],[3,4],[5,6]]
, left = 2
, right = 5
covered
as an array of zeros (size 52 to cover up to 50 and edge cases).
[1,2]
: covered[1] += 1
, covered[3] -= 1
[3,4]
: covered[3] += 1
, covered[5] -= 1
[5,6]
: covered[5] += 1
, covered[7] -= 1
covered[i]
will be the number of ranges covering i
.True
.
[left, right]
(up to 50 numbers), check all ranges (up to 50 ranges): O(N * R).The problem asks us to determine if every integer in a target interval is covered by a set of ranges. By using a difference array and prefix sums, we efficiently mark and check coverage for all numbers with minimal computation. This approach leverages the small, fixed domain of possible numbers for quick and elegant verification, making it both practical and easy to implement.
class Solution:
def isCovered(self, ranges, left, right):
covered = [0] * 52 # since numbers go up to 50, index 51 is safe
for start, end in ranges:
covered[start] += 1
if end + 1 < len(covered):
covered[end + 1] -= 1
# Prefix sum
for i in range(1, 52):
covered[i] += covered[i - 1]
# Check coverage
for num in range(left, right + 1):
if covered[num] == 0:
return False
return True
class Solution {
public:
bool isCovered(vector<vector<int>>& ranges, int left, int right) {
int covered[52] = {0};
for (const auto& range : ranges) {
int start = range[0], end = range[1];
covered[start] += 1;
if (end + 1 < 52)
covered[end + 1] -= 1;
}
for (int i = 1; i < 52; ++i)
covered[i] += covered[i - 1];
for (int num = left; num <= right; ++num) {
if (covered[num] == 0)
return false;
}
return true;
}
};
class Solution {
public boolean isCovered(int[][] ranges, int left, int right) {
int[] covered = new int[52];
for (int[] range : ranges) {
int start = range[0], end = range[1];
covered[start] += 1;
if (end + 1 < covered.length)
covered[end + 1] -= 1;
}
for (int i = 1; i < 52; ++i)
covered[i] += covered[i - 1];
for (int num = left; num <= right; ++num) {
if (covered[num] == 0)
return false;
}
return true;
}
}
var isCovered = function(ranges, left, right) {
let covered = new Array(52).fill(0);
for (const [start, end] of ranges) {
covered[start] += 1;
if (end + 1 < covered.length)
covered[end + 1] -= 1;
}
for (let i = 1; i < 52; ++i)
covered[i] += covered[i - 1];
for (let num = left; num <= right; ++num) {
if (covered[num] === 0)
return false;
}
return true;
};