一、题目描述
小明正在设计一台打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。小明需要你帮助他计算,在给定的多组数字范围内,计数器会打多少个点。
例如,给定三个数字范围 [1, 4], [7, 10], 和 [3, 5],计数器首先将这些范围合并,变成 [1, 5] 和 [7, 10],然后计算这两个范围内共有多少个唯一数字,即从 1 到 5 有 5 个数字,从 7 到 10 有 4 个数字,共打 9 个点。
二、解题思路
- 排序:首先将所有区间按起始位置排序,这样可以方便后续的区间合并。
- 合并区间:遍历排序后的区间,合并重叠的区间。
- 计算点数:统计合并后的区间中的点数。
三、代码实现
import java.util.Arrays;
public class Main {
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]));
// 用于合并区间的列表
int[] merged = inputArray[0].clone();
int count = 0;
for (int[] interval : inputArray) {
if (interval[0] > merged[1]) {
// 当前区间与已合并区间无重叠,增加新的合并区间
count += merged[1] - merged[0] + 1;
merged = interval.clone();
} else {
// 当前区间与已合并区间有重叠,合并区间
merged[1] = Math.max(merged[1], interval[1]);
}
}
// 添加最后一个合并区间的点数
count += merged[1] - merged[0] + 1;
return count;
}
public static void main(String[] args) {
int[][] testArray1 = {{1, 4}, {7, 10}, {3, 5}};
int[][] testArray2 = {{1, 2}, {6, 10}, {11, 15}};
int[][] testArray3 = {{1, 3}, {2, 6}, {8, 10}};
System.out.println(solution(testArray1) == 9); // true
System.out.println(solution(testArray2) == 12); // true
System.out.println(solution(testArray3) == 9); // true
}
}
四、代码解释
-
排序:
- 使用
Arrays.sort方法按起始位置对区间进行排序。
- 使用
-
合并区间:
-
初始化
merged数组为第一个区间的副本。 -
遍历排序后的区间:
- 如果当前区间的起始位置大于已合并区间的结束位置,说明没有重叠,增加新的合并区间并更新计数。
- 如果当前区间的起始位置小于或等于已合并区间的结束位置,说明有重叠,合并区间并更新
merged数组的结束位置。
-
-
计算点数:
- 在遍历过程中,每次发现一个新的合并区间时,增加该区间的点数。
- 最后,添加最后一个合并区间的点数。
五、总结与反思
-
关键点:
- 排序:排序是解决区间合并问题的关键步骤,它使得我们可以线性地遍历区间并合并重叠部分。
- 合并区间:通过维护一个当前合并区间的变量,可以在遍历过程中高效地合并重叠区间。
-
改进方法:
- 优化排序:虽然
Arrays.sort的时间复杂度为 O(n log n),但对于大数据量的输入,可以考虑使用更高效的排序算法。 - 空间优化:当前实现中使用了一个
merged数组来存储当前合并的区间,可以考虑使用更少的空间来存储中间结果。
- 优化排序:虽然
-
应用场景:
- 日志分析:在日志分析中,可以使用类似的方法来合并时间段,以便更高效地统计日志事件。
- 资源分配:在资源分配问题中,可以使用区间合并来优化资源的分配,避免资源浪费。
六、个人思考
通过解决这个问题,我深刻体会到了排序和区间合并的重要性。在实际开发中,很多问题都可以通过类似的思路来解决。例如,在日志分析中,我们经常需要合并时间段来统计事件的发生次数。通过这个练习,我不仅巩固了算法知识,还提升了对实际问题的解决能力。希望能用好豆包AI这个工具来帮助自己更好刷题
七、不足之处与提升方向
- 多做练习:多做一些类似的区间合并问题,可以加深对算法的理解。
- 理解核心思想:理解排序和区间合并的核心思想,做到解决其他问题时举一反三。
- 实际应用:尝试将这些算法应用到实际项目中,可以更好地巩固所学知识。