打点计数器区间合并问题解析与实现 | 豆包MarsCode AI刷题

75 阅读4分钟

打点计数器区间合并问题解析与实现

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. 区间排序:将所有输入区间按起始点从小到大排序,以便能快速找到相邻的区间。
  2. 区间合并:遍历排序后的区间,检查相邻区间之间是否重叠。若有重叠,将它们合并成一个新的区间;否则,将当前区间的长度记录为独特数字数量,然后开始下一区间的合并计算。
  3. 统计独特数字数量:合并完所有区间后,累加每个合并区间内的数字数量。

image.png

如图中所画,区间[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. 代码讲解与思路分析

在这段代码中,主要的操作流程如下:

  1. 处理边界情况:如果输入为空,直接返回 0。
  2. 排序区间:使用 Arrays.sort 对输入区间按起始值排序。
  3. 合并与统计:对于每个区间,我们检查它是否与当前正在处理的区间重叠:
    • 若重叠,则更新当前区间的结束位置为二者的最大结束位置,以实现合并。
    • 若不重叠,则计算当前区间的长度并累加至总点数,并更新当前区间为下一个区间。
  4. 最后处理:在循环结束后,处理最后一个区间,计算其长度并加入总点数。

这种算法时间复杂度为 (O(n \log n)),排序操作占主导;空间复杂度为 (O(1)),只使用了少量辅助变量,适合处理中小规模的区间合并问题。

5. 个人思考

在实际开发中,可能需要对更复杂的区间合并问题进行处理,比如:

  • 大数据场景优化:对于特别大量的数据,可以考虑使用并行计算来加速区间排序和合并过程,尤其在多线程环境下可以充分利用硬件资源。
  • 动态区间合并:有些应用场景中,区间可能是动态加入的,而非一次性输入。这种情况下可以使用动态数据结构(如平衡树)来高效管理和合并区间,保持实时性。