Examples of merging and inserting intervals by tail recursion and examples of ending recursion intervals
Requirement Description
There is a range list of ranges [[0, 2], [4, 6], [8, 10], [12, 14], sorted in order, there is no intersection. Now there is a new range of range_new [4, 9] For merging.
Using recursive thinking, you can use range_new to compare the range in sequence with ranges.
If range_new is a subset, return directly
If range_new is smaller than the current range, insert directly on the left
If range_new is greater than the current range, the range on the Right of recursive ranges is compared.
If range_new has an intersection, calculate the Union set and delete the current range. If the maximum value changes, compare it with the range on the right of the Union set recursion ranges. If the maximum value does not change, replace it with the current range.
Implementation
Returns the status code of the Union set.-1 indicates insert on the left, 1 indicates recursive traversal on the right, and 2 indicates that the current range needs to be updated and compared with the following range, 0 indicates that the current range is replaced.
# Union
Def xor (range_old, range_new ):
# Insert left: the maximum value of the new range is smaller than the minimum value of the old range.
If range_new [1] <range_old [0]:
Return-1, range_new
# Insert right: the new minimum value is greater than the maximum value in the old range.
Elif range_new [0]> range_old [1]:
Return 1, range_new
# Intersection exists
Else:
# Minimum value update
If range_new [0] <range_old [0]:
# [Minimum value update] does not need to traverse the list
If range_new [1] <range_old [1]:
Return 0, [range_new [0], range_old [1]
# [Minimum maximum value update], you need to determine whether the maximum value and the following range have an intersection
Else:
Return 2, range_new
# Update is not required for minimum values.
Else:
# [Not updated] the maximum value does not need to be updated.
If range_new [1] <= range_old [1]:
Return 0, None
# [Maximum value update], you need to determine whether the maximum value and the following range have an intersection
Else:
Return 2, [range_old [0], range_new [1]
# Tail recursion
Def tail_rescuvie (ranges, range_new, start = 0 ):
Print ('start: ', range_new)
# Insert at the end of ranges
If start> = len (ranges ):
Ranges. append (range_new)
Return
Result, range_or = xor (ranges [start], range_new)
# Insert on the left
If result =-1:
Ranges. insert (start, range_new)
# Continue traversing the right
Elif result = 1:
Tail_rescuvie (ranges, range_new, start + 1)
# Replacement
Elif result = 0:
If range_or is not None:
Ranges [start] = range_or
Return
# Delete a range and use the new range to continue backward recursion
Elif result = 2:
Del ranges [start]
Print ('rescuvie: ', start, range_new, range_or)
Return tail_rescuvie (ranges, range_or, start)
Else:
Pass
If _ name _ = '_ main __':
# Ranges = [] # [1, 2], [8, 9], [100,200], [205,300]
Import time
Ranges = [[x, x + 2] for x in range (0, 15, 4)]
Print 'ranges: ', ranges
Start = time. time ()
Tail_rescuvie (ranges, [4, 9])
Print 'ranges: ', ranges
Print 'cost: ', time. time ()-start
The execution result is as follows:
Ranges: [[0, 2], [4, 6], [8, 10], [12, 14]
('Start: ', [4, 9]) and [0, 2]
('Start: ', [4, 9 ]).
('Rescuvie: ', 1, [4, 9], [4, 9])
('Start: ', [4, 9]) and [8, 10]
Ranges: [[0, 2], [4, 10], [12, 14]
Cost: 0.00200009346008
Code optimization
If Intersection Processing exists, optimize the code, extract the new Union result, and directly compare it with the following range.
# Tail recursion
Def tail_rescuvie (ranges, range_new, start = 0 ):
Print ('start: ', range_new, Start)
# Insert at the end of ranges
If start> = len (ranges ):
Ranges. append (range_new)
Return
# Insert on the left
If range_new [1] <ranges [start] [0]:
Ranges. insert (start, range_new)
# Recursive Traversal
Elif range_new [0]> ranges [start] [1]:
Tail_rescuvie (ranges, range_new, start + 1)
# Extract the new range and recursively traverse it later
Else:
Range_or = [min (range_new [0], ranges [start] [0]), max (range_new [1], ranges [start] [1])]
Del (ranges [start])
Tail_rescuvie (ranges, range_or, start)
if __name__ == '__main__':
# ranges = [] # [[1, 2], [8, 9], [100, 200], [205, 300]]
import time
ranges = [[x, x+2] for x in range(0, 15, 4)]
print 'ranges:', ranges
start = time.time()
tail_rescuvie(ranges, [4, 9])
print 'ranges:', ranges
print 'cost:', time.time() - start
ranges = []
tail_rescuvie(ranges, [0, 1])
tail_rescuvie(ranges, [4, 8])
tail_rescuvie(ranges, [1, 3])
print 'ranges:', ranges
tail_rescuvie(ranges, [3, 5])
print 'ranges:', ranges