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

49 阅读4分钟

题目理解

题目要求我们设计一个打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。我们需要计算在给定的多组数字范围内,计数器会打多少个点。

解题思路

  1. 排序区间:首先,我们可以对所有区间按起始点进行排序。这样可以帮助我们更容易地合并重叠的区间。
  2. 合并区间:遍历排序后的区间,如果当前区间的起始点小于或等于前一个区间的结束点,则说明这两个区间有重叠,可以合并。否则,将前一个区间加入结果列表,并开始一个新的区间。
  3. 计算总长度:合并完所有区间后,计算每个区间的长度并累加。

数据结构选择

  • 列表:我们使用Python的列表来存储区间。列表的排序和遍历操作非常方便。
  • 元组:每个区间用一个元组表示,例如 (start, end)

算法步骤

  1. 排序:对输入的区间列表按起始点进行排序。

  2. 初始化:创建一个空的结果列表 merged_intervals 和一个当前区间 current_interval,初始值为排序后的第一个区间。

  3. 遍历区间:从第二个区间开始遍历,检查当前区间是否与前一个区间重叠。

    • 如果重叠,合并这两个区间。
    • 如果不重叠,将前一个区间加入结果列表,并更新当前区间为当前遍历的区间。
  4. 添加最后一个区间:遍历结束后,将最后一个区间加入结果列表。

  5. 计算总长度:遍历合并后的区间列表,计算每个区间的长度并累加。

代码实现

def solution(inputArray):

    # 1. 对区间按起始点进行排序

    inputArray.sort(key=lambda x: x[0])

   
    # 2. 初始化结果列表和当前区间

    merged_intervals = []

    current_interval = inputArray[0]

    
    # 3. 遍历所有区间

    for interval in inputArray[1:]:

        # 如果当前区间与前一个区间重叠,合并它

        们

        if interval[0] <= 

        current_interval[1]:

            current_interval[1] = max

            (current_interval[1], 

            interval[1])

        else:

            # 否则,将前一个区间加入结果列表,

            并更新当前区间

            merged_intervals.append

            (current_interval)

            current_interval = interval

    
    # 4. 将最后一个区间加入结果列表

    merged_intervals.append

    (current_interval)


    # 5. 计算合并后区间的总长度

    total_length = 0

    for interval in merged_intervals:

        total_length += interval[1] - 

        interval[0] + 1

    
    return total_length

if __name__ == "__main__":

    testArray1 = [[1,4], [710], [35]]

    testArray2 = [[1,2], [610], [11, 

    15]]

    print(solution(testArray1) == 9 )

    print(solution(testArray2) == 12 )

代码解释

  1. 排序inputArray.sort(key=lambda x: x[0]) 这行代码按区间的起始点对所有区间进行排序。

  2. 初始化merged_intervals 用于存储合并后的区间,current_interval 用于存储当前正在处理的区间。

  3. 遍历区间

    • if interval[0] <= current_interval[1]:检查当前区间是否与前一个区间重叠。
    • current_interval[1] = max(current_interval[1], interval[1]):如果重叠,合并这两个区间。
    • merged_intervals.append(current_interval):如果不重叠,将前一个区间加入结果列表。
  4. 添加最后一个区间:遍历结束后,将最后一个区间加入结果列表。

  5. 计算总长度:遍历合并后的区间列表,计算每个区间的长度并累加。

测试样例

  • 样例1inputArray = [[1, 4], [7, 10], [3, 5]]

    • 排序后:[[1, 4], [3, 5], [7, 10]]
    • 合并后:[[1, 5], [7, 10]]
    • 总长度:(5 - 1 + 1) + (10 - 7 + 1) = 5 + 4 = 9
  • 样例2inputArray = [[1, 2], [6, 10], [11, 15]]

    • 排序后:[[1, 2], [6, 10], [11, 15]]
    • 合并后:[[1, 2], [6, 10], [11, 15]]
    • 总长度:(2 - 1 + 1) + (10 - 6 + 1) + (15 - 11 + 1) = 2 + 5 + 5 = 12
  • 样例3inputArray = [[1, 3], [2, 6], [8, 10]]

    • 排序后:[[1, 3], [2, 6], [8, 10]]
    • 合并后:[[1, 6], [8, 10]]
    • 总长度:(6 - 1 + 1) + (10 - 8 + 1) = 6 + 3 = 9

复杂度分析

  • 时间复杂度:排序的时间复杂度为 O(n log n),遍历区间的时间复杂度为 O(n),因此总时间复杂度为 O(n log n)
  • 空间复杂度:主要的空间消耗在于存储合并后的区间,空间复杂度为 O(n)

总结

通过排序和遍历,我们可以有效地合并重叠的区间,并计算合并后区间的总长度。这个算法的时间复杂度为 O(n log n),空间复杂度为 O(n),适用于大多数实际场景。

进一步优化

  • 优化排序:如果输入的区间已经有序,可以跳过排序步骤,直接进行合并,从而将时间复杂度降低到 O(n)
  • 优化空间:如果不需要存储合并后的区间,可以直接在遍历过程中计算总长度,从而将空间复杂度降低到 O(1)

通过这份详细的做题笔记,我们可以更好地理解题目的要求,掌握解题思路,并实现高效的代码。希望这份笔记对你有所帮助!