问题描述
小明想发明一台打点计数器,这个计数器有这样的一个功能:
-
它可以接收一个递增的数据范围(形如[3, 9]),其中第一个数字代表起始,第二个数字代表结束
-
这个数据范围中包含几个数字,打点计数器就会打几个点
-
在传入的多组数据范围中,如果出现了范围的重复,机器则不会重复打点
你可以帮助小明算一算,在不同的情况下,计数器会打出几个点么?
输入格式
一个二维数组
输出格式
一个整数,表达在输入是这个数组的情况下,计数器打出的点数
输入样例(1)
[ [1,4], [7, 10], [3, 5] ]
输出样例(1)
7
输入样例(2)
[ [1,2], [6, 10], [11, 15] ]
输出样例(2)
9
数据范围
- 数字范围 [-10^9, 10^9],数组长度 < 2^16
题解
- 排序:首先对区间按起始值进行排序,确保我们能顺序处理区间。
- 合并:遍历排序后的区间列表,合并重叠的区间,确保没有重复计数。
- 计算长度:合并后的区间长度之和即为所需的结果。 小明正在开发的打点计数器需要能够处理多个重叠的数字范围,并计算出所有不同数字的数量。为了解决这个问题,我们需要对输入的区间进行处理,确保没有重复计数。
解决方案
- 排序区间:首先,我们需要对输入的区间按起始值进行排序。这是为了方便后续的合并操作,使我们能顺序地处理每个区间。
- 合并区间:遍历排序后的区间列表,合并所有重叠或相邻的区间。这样可以确保每个数字只被计数一次。
- 计算点数:合并后的区间长度之和就是计数器需要打出的点数。
详细步骤
-
排序:对输入的二维数组按每个子数组的第一个元素进行排序。
-
合并逻辑:
-
初始化一个空列表
merged_ranges来存储合并后的区间。 -
使用变量
current_start和current_end来追踪当前正在合并的区间。 -
遍历排序后的区间:
- 如果当前区间的起始值小于等于
current_end,则说明它们重叠或相邻,更新current_end为两个区间结束值的较大者。 - 如果不重叠,则将当前合并好的区间添加到
merged_ranges,并更新current_start和current_end为新的区间的起始和结束值。
- 如果当前区间的起始值小于等于
-
遍历结束后,将最后一个合并好的区间加入
merged_ranges。
-
-
计算结果:
- 遍历
merged_ranges,计算每个合并区间的长度,并累加得到总长度。 - 返回总长度作为计数器打出的点数。
- 遍历
示例解释
示例 1: 输入:[[1,4], [7, 10], [3, 5]]
-
排序后:
[[1, 4], [3, 5], [7, 10]] -
合并过程:
[1, 4]和[3, 5]重叠,合并为[1, 5][1, 5]和[7, 10]不重叠,直接加入
-
合并结果:
[[1, 5], [7, 10]] -
计算长度:
(5 - 1 + 1) + (10 - 7 + 1) = 5 + 4 = 9
示例 2: 输入:[[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
def solution(inputArray):
if not inputArray:
return 0
# 按开始值排序
inputArray.sort()
# 合并重复的区间
merged_ranges = []
current_start, current_end = inputArray[0]
for start, end in inputArray[1:]:
if start <= current_end:
# 如果重合了就合并
current_end = max(current_end, end)
else:
# 没有重合就当他是新的开始
merged_ranges.append((current_start, current_end))
current_start, current_end = start, end
# 加上最后一段
merged_ranges.append((current_start, current_end))
# print(merged_ranges)
# 计算总共需要打点的长度,注意样例其实是开始位置打点,结尾不大点
total_points = sum(end - start +1 for start, end in merged_ranges)
print(total_points)
return total_points
if __name__ == "__main__":
# You can add more test cases here
testArray1 = [[1,4], [7, 10], [3, 5]]
testArray2 = [[1,2], [6, 10], [11, 15]]
print(solution(testArray1) == 9 )
print(solution(testArray2) == 11 )