问题描述
小明正在设计一台打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。小明需要你帮助他计算,在给定的多组数字范围内,计数器会打多少个点。
例如,给定三个数字范围 [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
解题思路
-
排序:通过排序,我们可以确保区间是按起始值从小到大排列的,这样在合并时可以更方便地处理重叠区间。
-
合并区间:我们遍历每个区间,如果当前区间的起始值大于最后一个合并区间的结束值,说明它们不重叠,直接加入合并后的区间列表;否则,更新最后一个合并区间的结束值。
-
计算唯一数字的数量:合并后的区间可以直接计算其长度,即区间的结束值减去开始值再加1。
代码实现
def solution(inputArray):
inputArray.sort(key=lambda x: x[0])
merged_intervals = []
for interval in inputArray:
if not merged_intervals or interval[0] > merged_intervals[-1][1]:
merged_intervals.append(interval)
else:
merged_intervals[-1][1] = max(merged_intervals[-1][1], interval[1])
count = 0
for interval in merged_intervals:
count += interval[1] - interval[0] + 1
return count
if __name__ == "__main__":
testArray1 = [[1,4], [7, 10], [3, 5]]
testArray2 = [[1,2], [6, 10], [11, 15]]
print(solution(testArray1) == 9 )
print(solution(testArray2) == 12 )
知识点总结
-
排序(Sorting)
- 知识点:排序算法,特别是基于比较的排序算法(如快速排序、归并排序)。
- 应用:在这个问题中,我们使用排序来确保区间按起始值从小到大排列,以便于后续的合并操作。
- 知识点:排序算法,特别是基于比较的排序算法(如快速排序、归并排序)。
-
列表操作(List Operations)
- 知识点:列表的创建、访问、修改、遍历等基本操作。
- 应用:使用列表来存储输入的区间和合并后的区间,并通过遍历列表来处理每个区间。
-
区间合并(Interval Merging)
- 知识点:区间合并算法,通常用于处理重叠区间的问题。
- 应用:通过比较当前区间的起始值和最后一个合并区间的结束值来决定是否合并区间。
-
Lambda函数(Lambda Functions)
- 知识点:匿名函数,用于定义简单的、一次性使用的函数。
- 应用:使用lambda函数作为排序的关键字,以便按区间的起始值进行排序。
相关拓展
拓展相关知识点
-
数据结构
- 堆(Heap) :堆是一种特殊的树形数据结构,常用于实现优先队列。在处理区间问题时,堆可以用于动态地获取最小或最大的区间。
- 树(Tree) :树结构可以用于表示区间之间的关系,例如区间树(Interval Tree)可以高效地查询重叠区间。
-
算法
- 贪心算法(Greedy Algorithm) :贪心算法通常用于解决最优化问题,通过每一步的最优选择来达到全局最优。区间合并问题可以用贪心算法来解决。
- 动态规划(Dynamic Programming) :动态规划适用于解决具有重叠子问题和最优子结构的问题。虽然在这个问题中没有直接使用动态规划,但类似的问题可以用动态规划来解决。