打点计数器的区间合并 | 豆包MarsCode AI刷题

111 阅读4分钟

一、题目描述

小明正在设计一台打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。小明需要你帮助他计算,在给定的多组数字范围内,计数器会打多少个点。

例如,给定三个数字范围 [1, 4], [7, 10], 和 [3, 5],计数器首先将这些范围合并,变成 [1, 5] 和 [7, 10],然后计算这两个范围内共有多少个唯一数字,即从 1 到 5 有 5 个数字,从 7 到 10 有 4 个数字,共打 9 个点。

二、解题思路

  1. 排序:首先将所有区间按起始位置排序,这样可以方便后续的区间合并。
  2. 合并区间:遍历排序后的区间,合并重叠的区间。
  3. 计算点数:统计合并后的区间中的点数。

三、代码实现

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
    }
}

四、代码解释

  1. 排序

    • 使用 Arrays.sort 方法按起始位置对区间进行排序。
  2. 合并区间

    • 初始化 merged 数组为第一个区间的副本。

    • 遍历排序后的区间:

      • 如果当前区间的起始位置大于已合并区间的结束位置,说明没有重叠,增加新的合并区间并更新计数。
      • 如果当前区间的起始位置小于或等于已合并区间的结束位置,说明有重叠,合并区间并更新 merged 数组的结束位置。
  3. 计算点数

    • 在遍历过程中,每次发现一个新的合并区间时,增加该区间的点数。
    • 最后,添加最后一个合并区间的点数。

五、总结与反思

  1. 关键点

    • 排序:排序是解决区间合并问题的关键步骤,它使得我们可以线性地遍历区间并合并重叠部分。
    • 合并区间:通过维护一个当前合并区间的变量,可以在遍历过程中高效地合并重叠区间。
  2. 改进方法

    • 优化排序:虽然 Arrays.sort 的时间复杂度为 O(n log n),但对于大数据量的输入,可以考虑使用更高效的排序算法。
    • 空间优化:当前实现中使用了一个 merged 数组来存储当前合并的区间,可以考虑使用更少的空间来存储中间结果。
  3. 应用场景

    • 日志分析:在日志分析中,可以使用类似的方法来合并时间段,以便更高效地统计日志事件。
    • 资源分配:在资源分配问题中,可以使用区间合并来优化资源的分配,避免资源浪费。

六、个人思考

通过解决这个问题,我深刻体会到了排序和区间合并的重要性。在实际开发中,很多问题都可以通过类似的思路来解决。例如,在日志分析中,我们经常需要合并时间段来统计事件的发生次数。通过这个练习,我不仅巩固了算法知识,还提升了对实际问题的解决能力。希望能用好豆包AI这个工具来帮助自己更好刷题

七、不足之处与提升方向

  1. 多做练习:多做一些类似的区间合并问题,可以加深对算法的理解。
  2. 理解核心思想:理解排序和区间合并的核心思想,做到解决其他问题时举一反三。
  3. 实际应用:尝试将这些算法应用到实际项目中,可以更好地巩固所学知识。