问题描述
小明正在设计一台打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。小明需要你帮助他计算,在给定的多组数字范围内,计数器会打多少个点。
例如,给定三个数字范围 [1, 4], [7, 10], 和 [3, 5],计数器首先将这些范围合并,变成 [1, 5] 和 [7, 10],然后计算这两个范围内共有多少个唯一数字,即从 1 到 5 有 5 个数字,从 7 到 10 有 4 个数字,共打 9 个点。
思路解析
这个问题的关键在于如何合并给定的区间,并计算合并后的区间内的数字个数。首先,我们要了解如何合并重叠的区间,并根据合并后的区间来统计唯一的数字个数。
1. 排序
首先,对给定的区间按起始位置进行排序。这样可以确保我们能够依次比较相邻区间是否重叠。
2. 合并区间
对于每个区间,如果当前区间的起始值大于前一个区间的结束值,那么说明这两个区间没有重叠,我们可以直接把当前区间加入结果中。如果当前区间的起始值小于等于前一个区间的结束值,那么就需要合并两个区间,合并后的区间的起始值不变,结束值取两个区间结束值中的最大值。
3. 计算唯一点的数量
合并完所有区间之后,我们只需要计算每个合并后的区间内包含的数字个数。每个合并后的区间的数字个数可以通过 (end - start + 1) 来得到。
4. 计算总点数
将所有合并后的区间的数字个数相加,即可得到最终的打点数量。
图解说明
假设我们有三个区间:[1, 4], [7, 10], [3, 5]。
-
排序阶段:
- 排序后得到
[[1, 4], [3, 5], [7, 10]]
- 排序后得到
-
合并阶段:
- 处理
[1, 4]和[3, 5],它们有重叠,因此合并成[1, 5]。 [1, 5]和[7, 10]没有重叠,保持[7, 10]不变。
- 处理
-
计算点数:
[1, 5]中有 5 个点,[7, 10]中有 4 个点,因此总点数为 9。
代码详解
python
复制代码
def solution(inputArray):
# 按照区间的起始值排序
inputArray.sort()
merged = []
for interval in inputArray:
# 如果 merged 为空或当前区间与 merged 中最后一个区间不重叠
if not merged or merged[-1][1] < interval[0]:
merged.append(interval)
else:
# 合并区间
merged[-1][1] = max(merged[-1][1], interval[1])
# 计算合并后所有区间的数字个数
count = 0
for interval in merged:
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) # 输出:9
print(solution(testArray2) == 12) # 输出:12
代码解释:
- 排序:首先,按区间的起始值对输入数组进行排序。排序后,我们可以确保合并区间时,前面的区间总是比后面的区间早到。
- 合并区间:遍历排序后的区间。如果当前区间与合并后的最后一个区间重叠,我们就将其合并。如果不重叠,就将当前区间直接加入到结果中。
- 计算点数:最后,我们遍历合并后的区间,计算每个区间的点数(即区间长度),并将它们加总。
关键思路总结
- 区间排序:排序是合并区间的前提,通过对区间的起始值排序,我们能有效地判断哪些区间有重叠。
- 区间合并:在遍历过程中,如果两个区间有重叠,我们就需要合并它们。这是解决这个问题的核心。
- 计算点数:通过合并后的区间来计算唯一点数,合并过程保证了不会重复计数。
知识总结与个人思考
在这道题中,我不仅巩固了合并区间的基本操作,还深入理解了排序和遍历的应用。通过对区间的合并,我们可以将多个可能重叠的区间合并成一个,这在许多实际问题中都有应用,比如计算连续时间段、资源分配等。
对于其他入门同学的学习建议:
- 理解基本数据结构的操作:这道题考察了区间的合并,理解排序、比较、合并等基本操作是解决这类问题的关键。掌握这些基础操作对于后续更复杂的问题解决至关重要。
- 动手实践:刷题不仅仅是阅读解法,更多的是要动手写代码并进行调试。通过动手实践,才能更好地理解问题的本质。
- 算法优化:这道题的时间复杂度是
O(n log n),其中n是区间的数量,排序是主导因素。如果遇到更复杂的区间合并问题,可能还需要考虑更高效的算法。
总之,区间合并是一个非常常见且重要的算法技巧,掌握它将为你解决许多类型的问题打下坚实的基础。