打点计数器区间合并问题解析与实现
1. 问题描述
小明正在设计一台打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。小明需要你帮助他计算,在给定的多组数字范围内,计数器会打多少个点。
例如,给定三个数字范围 [1, 4], [7, 10], 和 [3, 5],计数器首先将这些范围合并,变成 [1, 5] 和 [7, 10],然后计算这两个范围内共有多少个唯一数字,即从 1 到 5 有 5 个数字,从 7 到 10 有 4 个数字,共打 9 个点。
测试样例
样例1:
输入:
inputArray = [[1, 4], [7, 10], [3, 5]]
输出:9
样例2:
输入:
inputArray = [[1, 2], [6, 10], [11, 15]]
输出:12
样例3:
输入:
inputArray = [[1, 3], [2, 6], [8, 10]]
输出:9
2. 问题分析
首先我们可以分析一下问题的核心思路:
- 区间排序:将所有输入区间按起始点从小到大排序,以便能快速找到相邻的区间。
- 区间合并:遍历排序后的区间,检查相邻区间之间是否重叠。若有重叠,将它们合并成一个新的区间;否则,将当前区间的长度记录为独特数字数量,然后开始下一区间的合并计算。
- 统计独特数字数量:合并完所有区间后,累加每个合并区间内的数字数量。
如图中所画,区间[1,4]和区间[3-5]有重复区间,我们可以在[3,4]的区间打点来替代分别在两个区间打点,所以我们可以将区间合并为一个区间来看待。同理,如果有多个区间有重复区域,我们也可以在重复区域打点来替代相应的区间。
这种算法的关键在于排序和区间合并,二者能够确保我们高效处理所有输入区间并得到唯一的数字点数量。
这题非常像Leetcode的435题:无重叠区间 代码随想录中也收录了此题:代码随想录。
3. Java 实现
以下是完整的 Java 代码实现,通过排序和合并操作来解决该问题:
public int solution(int[][] inputArray) {
// 1. 输入为空的情况
if (inputArray.length == 0)
return 0;
// 2. 排序区间
Arrays.sort(inputArray, (a, b) -> Integer.compare(a[0], b[0]));
// 3. 合并区间
int totalPoints = 0;
int currentStart = inputArray[0][0];
int currentEnd = inputArray[0][1];
for (int i = 1; i < inputArray.length; i++) {
int[] nextInterval = inputArray[i];
if (currentEnd >= nextInterval[0]) {
// 有重叠,更新当前区间的结束值
currentEnd = Math.max(currentEnd, nextInterval[1]);
} else {
// 没有重叠,计算当前区间的点数
totalPoints += (currentEnd - currentStart + 1);
// 更新当前区间为下一个区间
currentStart = nextInterval[0];
currentEnd = nextInterval[1];
}
}
// 处理最后一个区间
totalPoints += (currentEnd - currentStart + 1);
return totalPoints;
}
4. 代码讲解与思路分析
在这段代码中,主要的操作流程如下:
- 处理边界情况:如果输入为空,直接返回 0。
- 排序区间:使用
Arrays.sort对输入区间按起始值排序。 - 合并与统计:对于每个区间,我们检查它是否与当前正在处理的区间重叠:
- 若重叠,则更新当前区间的结束位置为二者的最大结束位置,以实现合并。
- 若不重叠,则计算当前区间的长度并累加至总点数,并更新当前区间为下一个区间。
- 最后处理:在循环结束后,处理最后一个区间,计算其长度并加入总点数。
这种算法时间复杂度为 (O(n \log n)),排序操作占主导;空间复杂度为 (O(1)),只使用了少量辅助变量,适合处理中小规模的区间合并问题。
5. 个人思考
在实际开发中,可能需要对更复杂的区间合并问题进行处理,比如:
- 大数据场景优化:对于特别大量的数据,可以考虑使用并行计算来加速区间排序和合并过程,尤其在多线程环境下可以充分利用硬件资源。
- 动态区间合并:有些应用场景中,区间可能是动态加入的,而非一次性输入。这种情况下可以使用动态数据结构(如平衡树)来高效管理和合并区间,保持实时性。