我根据vallentin的回答做了一些改进,主要是使用copy.deepcopy
来防止对输入进行任何更改。
请注意,使用sorted()
或.copy()
是不够的,因为在发生任何合并时,子元素会被更改。
我还添加了对每个区间的.sort()
调用以处理未排序的输入,以及一个更明确的初始排序调用以提高清晰度。
代码:
import copy
def mergeIntervals(input_array, preserve_input=True):
'''
Python3 program for merging overlapping intervals.
If preserve_input is False, the input_array can be modified! Not just sorted, but even sub-elements can change!
See:
https://www.educative.io/answers/what-is-the-merge-overlapping-intervals-problem
https://www.geeksforgeeks.org/merging-intervals/
https://dev59.com/uFcP5IYBdhLWcg3w8eW5
'''
if preserve_input:
intervals = copy.deepcopy(input_array)
else:
intervals = input_array
intervals.sort(key=lambda interval: interval[0])
intervals[0].sort()
merged = [intervals[0]]
for current in intervals[1:]:
current.sort()
previous = merged[-1]
if current[0] <= previous[-1]:
previous[-1] = max(previous[-1], current[-1])
else:
merged.append(current)
return merged
A_list = []
input_array = [[-25, -14], [-21, -16], [-20, -15], [-10, -7], [-8, -5], [-6, -3], [2, 4], [2, 3], [3, 6], [12, 15], [13, 18], [14, 17], [22, 27], [25, 30], [26, 29]]
A_list.append(input_array)
input_array = [[4, 2], [3, 1]]
A_list.append(input_array)
for preserve_input in [False, True]:
print(f'==> preserve_input = {preserve_input}')
for idx, a in enumerate(A_list):
print('------> idx = ', idx)
input_array = copy.deepcopy(a)
print('input before:', input_array)
output_array = mergeIntervals(input_array, preserve_input=preserve_input)
print('input after:', input_array)
print('output', output_array)
if input_array != a:
print('Input modified!')
if preserve_input:
raise
else:
print('No change in input.')
输出:
请特别注意第一个示例中的[22, 27]
在末尾附近变为[22, 30]
。
==> preserve_input = False
------> idx = 0
input before: [[-25, -14], [-21, -16], [-20, -15], [-10, -7], [-8, -5], [-6, -3], [2, 4], [2, 3], [3, 6], [12, 15], [13, 18], [14, 17], [22, 27], [25, 30], [26, 29]]
input after: [[-25, -14], [-21, -16], [-20, -15], [-10, -3], [-8, -5], [-6, -3], [2, 6], [2, 3], [3, 6], [12, 18], [13, 18], [14, 17], [22, 30], [25, 30], [26, 29]]
output [[-25, -14], [-10, -3], [2, 6], [12, 18], [22, 30]]
Input modified!
------> idx = 1
input before: [[4, 2], [3, 1]]
input after: [[1, 4], [2, 4]]
output [[1, 4]]
Input modified!
==> preserve_input = True
------> idx = 0
input before: [[-25, -14], [-21, -16], [-20, -15], [-10, -7], [-8, -5], [-6, -3], [2, 4], [2, 3], [3, 6], [12, 15], [13, 18], [14, 17], [22, 27], [25, 30], [26, 29]]
input after: [[-25, -14], [-21, -16], [-20, -15], [-10, -7], [-8, -5], [-6, -3], [2, 4], [2, 3], [3, 6], [12, 15], [13, 18], [14, 17], [22, 27], [25, 30], [26, 29]]
output [[-25, -14], [-10, -3], [2, 6], [12, 18], [22, 30]]
No change in input.
------> idx = 1
input before: [[4, 2], [3, 1]]
input after: [[4, 2], [3, 1]]
output [[1, 4]]
No change in input.