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

62 阅读4分钟

问题描述

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

例如,给定三个数字范围 [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

题目解析:

我们需要计算给定的多个数字范围在合并后的唯一数字个数。通过合并重叠区间,我们可以避免重复计数,并求出最终的点数。

核心问题

  • 区间合并:多个区间可能会有重叠,要将这些重叠的区间合并成一个更大的区间。
  • 唯一数字计数:每个合并后的区间中只计数一次数字。

思路分析:

1. 排序

首先,对所有区间按起始位置进行排序。排序是为了确保我们可以按顺序遍历区间,便于合并重叠的区间。

2. 合并区间

  • 如果当前区间与已有的合并区间有重叠,则合并它们。
  • 否则,将当前区间添加为新的合并区间。

3. 计算唯一数字的个数

每次合并完一个区间后,计算该区间内的数字个数。对于每个合并后的区间 [start, end],该区间内的唯一数字个数为 end−start+1

4. 特殊情况

  • 如果输入的数组为空,我们直接返回 0。

解决方案:

代码实现:

def solution(inputArray):
    # 如果输入为空,返回 0
    if not inputArray:
        return 0
    
    # 步骤 1:按起始位置排序
    inputArray.sort(key=lambda x: x[0])

    # 步骤 2:合并区间
    merged_ranges = []
    for start, end in inputArray:
        # 如果 merged_ranges 为空或者当前区间不与最后一个合并区间重叠
        if not merged_ranges or merged_ranges[-1][1] < start:
            merged_ranges.append([start, end])
        else:
            # 合并区间
            merged_ranges[-1][1] = max(merged_ranges[-1][1], end)
    
    # 步骤 3:计算总的点数
    total_points = 0
    for start, end in merged_ranges:
        total_points += end - start + 1

    return total_points

代码解释:

  1. 输入检查:我们首先检查输入的区间数组是否为空。如果为空,直接返回 0。

  2. 排序:使用 sort() 函数按每个区间的起始位置对区间进行排序。排序后,合并操作变得简单,可以按顺序检查区间是否需要合并。

  3. 合并区间:遍历排序后的区间:

    • 如果当前区间与已合并的最后一个区间不重叠,则将其添加到 merged_ranges 列表中。
    • 如果有重叠,则将当前区间的结束值更新为两者的最大结束值,从而合并这两个区间。
  4. 计算总点数:对于每个合并后的区间,我们计算该区间内的数字个数,即 end−start+1,并将其累加。

示例测试:

  1. 样例1

    print(solution([[1,4], [7, 10], [3, 5]]))  # 输出 9
    
  2. 样例2

    print(solution([[1,2], [6, 10], [11, 15]])) # 输出 12
    

时间复杂度:

  • 排序:排序需要 O(nlogn)O(nlogn) 的时间,其中 nn 是区间的数量。
  • 合并操作:遍历所有区间,时间复杂度为 O(n)O(n)
  • 计算点数:对于每个合并后的区间,计算该区间的数字个数,时间复杂度为 O(n)O(n)

总体时间复杂度:O(nlogn)O(nlogn),主要来自于排序操作。

空间复杂度:

  • 合并区间:需要额外的空间来存储合并后的区间,空间复杂度为 O(n)O(n)

总结

这道题通过合并重叠区间并计算唯一数字个数来解决实际问题。通过对区间的排序和合并,可以高效地计算出最终的结果,避免了重复计数。该算法的时间复杂度是 O(nlogn)O(nlogn),适用于中等规模的数据集。