问题分析
本题的核心是处理多个递增的数字区间,要求我们计算所有区间合并后的唯一数字数量。对于给定的多个数字范围,若有重叠,则需要合并这些重叠的区间,最后计算合并后的区间所覆盖的唯一数字总数。
关键要求:
- 给定多个区间,需要合并那些有重叠的区间。
- 对于合并后的区间,计算区间内包含的唯一数字的总数。
解题思路
- 排序:首先,需要将输入的区间按照起始值排序,这样可以方便地通过一次遍历来合并重叠的区间。
- 区间合并:使用一个列表
mergedIntervals
来存储合并后的区间。我们从第一个区间开始,遍历后续区间。如果当前区间与正在处理的区间有重叠(即当前区间的起始值小于等于当前区间的结束值),则合并这两个区间;如果没有重叠,则将当前区间添加到mergedIntervals
中,并更新正在处理的区间。 - 计算点数:一旦所有区间都合并完成,遍历合并后的区间列表,计算每个区间的长度(即区间结束值减去起始值再加1),累加所有区间的长度得到最终的结果。
- 边界情况:考虑输入为空或没有区间的情况,直接返回0。
代码实现
import java.util.*;
public class Solution {
public static int solution(int[][] inputArray) {
if (inputArray == null || inputArray.length == 0) {
return 0;
}
// 将输入的区间按照起始值排序
Arrays.sort(inputArray, (a, b) -> Integer.compare(a[0], b[0]));
// 用于存储合并后的区间
List<int[]> mergedIntervals = new ArrayList<>();
int[] currentInterval = inputArray[0];
mergedIntervals.add(currentInterval);
for (int[] interval : inputArray) {
int currentStart = currentInterval[0];
int currentEnd = currentInterval[1];
int nextStart = interval[0];
int nextEnd = interval[1];
// 判断是否重叠
if (nextStart <= currentEnd) {
// 合并区间
currentInterval[1] = Math.max(currentEnd, nextEnd);
} else {
// 不重叠,添加新的区间
currentInterval = interval;
mergedIntervals.add(currentInterval);
}
}
// 计算合并后区间的总长度
int totalPoints = 0;
for (int[] interval : mergedIntervals) {
totalPoints += (interval[1] - interval[0] + 1);
}
return totalPoints;
}
}
代码解析
-
排序:
- 我们使用
Arrays.sort
方法对inputArray
进行排序,排序规则是按照每个区间的起始值进行升序排列。 - 排序后的区间会帮助我们通过线性扫描来合并相邻的重叠区间。
- 我们使用
-
区间合并:
- 我们首先将第一个区间添加到
mergedIntervals
中,然后从第二个区间开始,逐一检查每个区间与当前区间是否有重叠。 - 如果有重叠,更新当前区间的结束值;如果没有重叠,则将当前区间加入结果,并将当前处理区间更新为新的区间。
- 我们首先将第一个区间添加到
-
计算合并后的区间总点数:
- 遍历所有合并后的区间,计算每个区间的长度(
end - start + 1
),并将长度累加起来得到最终的点数。
- 遍历所有合并后的区间,计算每个区间的长度(
-
空输入处理:
- 在开始计算之前,检查输入是否为空。如果是空数组或空区间数组,直接返回0。
时间复杂度分析
- 排序:排序操作的时间复杂度为
O(n log n)
,其中n
是区间的数量。 - 合并区间:遍历一次输入数组并合并区间的时间复杂度为
O(n)
,其中n
是区间的数量。 - 计算点数:计算所有合并后区间长度的时间复杂度为
O(n)
,其中n
是合并后的区间数。最坏情况下,所有区间都不重叠,因此合并后的区间数等于输入的区间数。
综上,整个算法的时间复杂度为 O(n log n)
,主要由排序操作决定。
测试用例分析
考虑几个测试样例来验证代码的正确性。
样例1: 输入:
inputArray = [[1, 4], [7, 10], [3, 5]]
输出:
9
- 合并后的区间为
[1, 5]
和[7, 10]
,其长度分别为 5 和 4,总长度为 9。
样例2: 输入:
inputArray = [[1, 2], [6, 10], [11, 15]]
输出:
12
- 合并后的区间为
[1, 2]
、[6, 10]
和[11, 15]
,其长度分别为 2、5 和 5,总长度为 12。
样例3: 输入:
inputArray = [[1, 3], [2, 6], [8, 10]]
输出:
9
- 合并后的区间为
[1, 6]
和[8, 10]
,其长度分别为 6 和 3,总长度为 9。
总结
本题通过排序和双指针(合并区间)方法来解决多个区间的合并问题,最终计算合并后的区间覆盖的唯一数字总数。通过这种方法,能够高效地处理区间合并问题,时间复杂度为 O(n log n)
,适合处理大量数据。