一、题目描述
有一组区间 [a0, b0], [a1, b1], … (a, b 表示起点, 终点),区间有可能重叠、相邻,重叠或相邻则可以合并为更大的区间;
给定一组连接器[x1, x2, x3, …](x 表示连接器的最大可连接长度,即 x>=gap),可用于将分离的区间连接起来,但两个分离区间之间只能使用1个连接器;
请编程实现使用连接器后,最少的区间数结果。
区间数量 <10000;a,b 均 <=10000;
连接器梳理 <10000; x <=10000;
二、输入描述
区间组:[1,10],[15,20],[18,30],[33,40]
连接器组:[5,4,3,2]
三、输出描述
1
说明:合并后:[1,10], [15,30], [33,40],使用 5, 3 两个连接器连接后只剩下 [1,40]
四、解题思路
- 读取输入的区间组和连接器组。
- 将区间组字符串解析为一个二维整数数组rangeArr,每个子数组表示一个区间的起点和终点。
- 将连接器组字符串解析为一个整数列表connectList,表示每个连接器的最大可连接长度。
- 对区间组按照起点进行升序排序。
- 创建一个链表mergeRanges,用于存储合并后的区间。
- 将第一个区间加入mergeRanges链表。
- 创建一个链表linked,用于存储相邻区间之间的间隔距离。
- 遍历区间组的剩余区间(从第二个区间开始):
- 获取mergeRanges链表的最后一个区间的起点和终点。
- 获取当前区间的起点和终点。
- 如果当前区间与最后一个区间重叠或相邻(起点小于等于最后一个区间的终点):
- 移除mergeRanges链表的最后一个区间。
- 更新最后一个区间的终点为当前区间的终点和最后一个区间的终点的较大值。
- 否则,将当前区间添加到mergeRanges链表中,并计算当前区间与上一个区间之间的间隔距离(r1 - b)。
- 将间隔距离添加到linked链表中。
- 对linked链表和connectList列表进行降序排序。
- 当connectList和linked都还有元素时:
- 如果connectList的最后一个元素大于等于linked的最后一个元素:
- 移除connectList的最后一个元素。
- 移除linked的最后一个元素。
- 如果connectList的最后一个元素大于等于linked的最后一个元素:
- 输出linked链表的长度加1作为结果。
五、Python算法源码
def calculate_min_intervals(range_arr, connect_list):
range_arr.sort(key=lambda x: x[0])
merge_ranges = [range_arr[0]]
linked = []
for i in range(1, len(range_arr)):
last = merge_ranges[-1]
a, b = last
r1, r2 = range_arr[i]
if r1 <= b:
merge_ranges.pop()
merge_ranges.append([a, max(b, r2)])
else:
linked.append(r1 - b)
merge_ranges.append(range_arr[i])
linked.sort(reverse=True)
connect_list.sort(reverse=True)
while connect_list and linked:
if connect_list.pop() >= linked[-1]:
linked.pop()
return len(linked) + 1
六、效果展示
1、输入
[1,10],[15,20],[18,30],[33,40]
[5,4,3,2]
2、输出
1
🏆下一篇:华为OD机试真题 Python 实现【相对开音节】【2022Q4 100分】,附详细解题思路
🏆本文收录于,华为OD机试(Python)真题(A卷+B卷)
每一题都有详细的答题思路、详细的代码注释、样例测试,订阅后,专栏内的文章都可看,可加入华为OD刷题群(私信即可),发现新题目,随时更新,全天CSDN在线答疑。