# Find Maximal Uncovered Ranges

You are given an integer n which is the length of a **0-indexed** array nums, and a **0-indexed** 2D-array ranges, which is a list of sub-ranges of nums (sub-ranges may **overlap**).

Each row ranges[i] has exactly 2 cells:

ranges[i][0], which shows the start of the ith range (inclusive)

ranges[i][1], which shows the end of the ith range (inclusive)

These ranges cover some cells of nums and leave some cells uncovered. Your task is to find all of the **uncovered **ranges with **maximal** length.

Return *a 2D-array *answer* of the uncovered ranges, ***sorted*** by the starting point in ***ascending order***.*

By all of the **uncovered** ranges with **maximal** length, we mean satisfying two conditions:

Each uncovered cell should belong to **exactly** one sub-range

There should **not exist** two ranges (l1, r1) and (l2, r2) such that r1 + 1 = l2

```
class Solution {
public int[][] findMaximalUncoveredRanges(int n, int[][] ranges) {
Arrays.sort(ranges, (a, b) -> a[0] - b[0]);
int last = -1;
List<int[]> ans = new ArrayList<>();
for (int[] range : ranges) {
int l = range[0], r = range[1];
if (last + 1 < l) {
ans.add(new int[] {last + 1, l - 1});
}
last = Math.max(last, r);
}
if (last + 1 < n) {
ans.add(new int[] {last + 1, n - 1});
}
return ans.toArray(new int[0][]);
}
}
```

```
class Solution:
def findMaximalUncoveredRanges(self, n: int, ranges: list[list[int]]) -> list[list[int]]:
ans = []
start = 0
for l, r in sorted(ranges):
if start < l:
ans.append([start, l - 1])
if start <= r:
start = r + 1
if start < n:
ans.append([start, n - 1])
return ans
```

Range covering problems, like this one, are common in competitive programming and coding interviews because they require careful management of overlapping or adjacent ranges. The general approach is to sort the ranges by their starting points and then process them one by one to identify any gaps. In this problem, the goal is to find all the maximal uncovered ranges, which means identifying sections of the array that are not covered by any given range. Sorting the ranges is a key step, as it allows you to efficiently check where gaps appear and where the ranges overlap.

The solution works by maintaining a pointer, start, to track the beginning of the next uncovered range. As you process each range, if there's a gap between start and the current range, you record that uncovered range. Then, you update start to the end of the current range plus one. The process continues until all ranges are processed, ensuring any leftover uncovered portions of the array are also captured. This approach ensures that each uncovered range is maximally long and doesn't overlap or leave adjacent gaps, a typical goal in range covering problems.

## Related Problems

Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return *an array of the non-overlapping intervals that cover all the intervals in the input*.

You are given an integer array nums. You are initially positioned at the array's **first index**, and each element in the array represents your maximum jump length at that position.

Return true* if you can reach the last index, or *false* otherwise*.

You are given an array of CPU tasks, each represented by letters A to Z, and a cooling time, n. Each cycle or interval allows the completion of one task. Tasks can be completed in any order, but there's a constraint: **identical** tasks must be separated by at least n intervals due to cooling time.

Return the *minimum number of intervals* required to complete all tasks.

Given an array nums with n integers, your task is to check if it could become non-decreasing by modifying **at most one element**.

We define an array is non-decreasing if nums[i] <= nums[i + 1] holds for every i (**0-based**) such that (0 <= i <= n - 2).