问题描述
小明正在设计一台打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。小明需要你帮助他计算,在给定的多组数字范围内,计数器会打多少个点。
例如,给定三个数字范围 [1, 4], [7, 10], 和 [3, 5],计数器首先将这些范围合并,变成 [1, 5] 和 [7, 10],然后计算这两个范围内共有多少个唯一数字,即从 1 到 5 有 5 个数字,从 7 到 10 有 4 个数字,共打 9 个点。
测试样例:
示例一:
输入:
inputArray = [[1, 4], [7, 10], [3, 5]]输出:
9
示例二:
输入:
inputArray = [[1, 2], [6, 10], [11, 15]]输出:
12
示例三:
输入:
inputArray = [[1, 3], [2, 6], [8, 10]]输出:
9
解题思路
-
转换范围格式:
- 使用列表推导式将输入的每个范围转换为起始和结束数字的元组。这一步是为了简化后续的比较和合并操作。
- 代码示例:
ranges = [(start, end) for start, end in inputArray]
-
排序:
- 使用
sort()方法对范围列表进行排序,确保按照起始数字的顺序处理范围,便于合并重叠的范围。 - 代码示例:
ranges.sort()
- 使用
-
初始化合并后的范围列表:
- 创建一个空列表
merged_ranges来存储合并后的范围。这个列表将用于存储最终合并后的范围。 - 代码示例:
merged_ranges = []
- 创建一个空列表
-
合并重叠范围:
-
遍历排序后的范围列表,使用条件判断来检查当前范围是否与
merged_ranges中的最后一个范围重叠。 -
如果不重叠,直接将当前范围添加到
merged_ranges中。 -
如果重叠,合并当前范围与
merged_ranges中的最后一个范围,更新结束数字为两者中的最大值。 -
代码示例:
python for current_start, current_end in ranges: if not merged_ranges or merged_ranges[-1][1] < current_start - 1: merged_ranges.append((current_start, current_end)) else: merged_ranges[-1] = (merged_ranges[-1][0], max(merged_ranges[-1][1], current_end))
-
-
计算总点数:
-
遍历
merged_ranges中的每个范围,计算每个范围包含的数字数量(结束数字减去起始数字加一),并将它们累加得到总数。 -
代码示例:
python total_points = sum(end - start + 1 for start, end in merged_ranges)
-
-
返回结果:
- 返回计算出的总点数,这是合并后所有范围内的唯一数字的总数。
- 代码示例:
return total_points
核心代码
def solution(inputArray):
# 将每个范围转换为起始和结束数字
ranges = [(start, end) for start, end in inputArray]
# 按起始数字排序
ranges.sort()
# 初始化合并后的范围列表
merged_ranges = []
for current_start, current_end in ranges:
# 如果合并后的范围列表为空,或者当前范围与合并列表中的最后一个范围不重叠
if not merged_ranges or merged_ranges[-1][1] < current_start - 1:
merged_ranges.append((current_start, current_end))
else:
# 否则,合并当前范围与合并列表中的最后一个范围
merged_ranges[-1] = (merged_ranges[-1][0], max(merged_ranges[-1][1], current_end))
# 计算合并后的范围内的数字总数
total_points = 0
for start, end in merged_ranges:
total_points += end - start + 1
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) == 12 )
核心知识
-
列表推导式:在Python中,列表推导式提供了一种简洁的方式来创建列表,特别是在需要对数据进行转换或过滤时。
-
排序:
sort()方法用于对列表进行排序,这是处理范围合并问题的关键步骤,因为它允许我们按照起始数字的顺序处理范围。 -
条件判断:在合并范围时,条件判断用于决定是添加新范围还是合并现有范围,这是实现范围合并逻辑的核心。
-
循环和累加:通过循环遍历合并后的范围列表,并使用累加来计算总点数,这是解决问题的最后一步。
-
范围合并:处理重叠范围的合并逻辑是解决这个问题的关键,它涉及到对当前范围与已合并范围的比较和合并。
总结
-
理解问题:首先,要清楚理解问题的要求,即计算多个数字范围合并后包含的唯一数字的总数。
-
数据结构选择:选择合适的数据结构来存储和处理范围信息,这里使用元组和列表。
-
排序的重要性:在合并范围之前对它们进行排序,可以简化合并逻辑,避免复杂的重叠检查。
-
合并逻辑:实现合并逻辑时,要注意处理范围的起始和结束点,确保正确合并重叠范围。
-
代码清晰性:在编写代码时,保持代码的可读性和清晰性,使用清晰的变量名和注释来解释关键步骤。
-
测试验证:通过添加测试案例来验证代码的正确性,确保所有逻辑都被正确实现。
-
性能考虑:在处理大量范围时,考虑算法的性能,如排序的时间复杂度和合并操作的效率。
使用豆包marscode AI的优势
-
快速理解问题:MarsCode AI能够帮助用户快速理解算法题的要求和限制条件,通过自然语言处理技术提供清晰的问题描述。
-
提供解题思路:AI可以基于大量的算法知识库,为用户提供解题的基本思路和可能的解决方案。
-
生成代码框架:MarsCode AI能够根据算法题的要求,快速生成代码框架,帮助用户节省编写初始代码的时间。
-
优化代码:AI可以分析用户编写的代码,提供优化建议,帮助用户改进算法的效率和性能。