Почему рекурсивно?
Это будет нормально работать и примерно в 10 раз быстрее, чем лучший рекурсивный алгоритм:
def minMax(array): return min(array),max(array)
Чтобы избежать повторного вызова каждого рекурсии, вы могли бы написать функцию следующим образом:
def minMax(array):
first,*rest = array # first,rest = array[0],array[1:]
if not rest : return first,first
subMin,subMax = minMax(rest)
return min(first,subMin), max(first,subMax)
Если вы хотите избежать максимального предела рекурсии (т.е. в большом списке), вы можете использовать двоичный подход, разделяющий массив на левую и правую части.при этом используются только уровни рекурсии log (n) (а также уменьшаются некоторые накладные расходы на обработку):
def minMax(array):
size = len(array)
if size == 1 : return array[0],array[0]
midPoint = size // 2
leftMin,leftMax = minMax(array[:midPoint])
rightMin,rightMax = minMax(array[midPoint:])
return min(leftMin,rightMin), max(leftMin,rightMin)
Если вы хотите уменьшить накладные расходы на создание массива и вызовы функций, вы можете передатьИндексируйте и избегайте min (), max () и len () (но тогда вы используете рекурсию как цикл for, который в значительной степени побеждает цель):
def minMax(array, index=None):
index = (index or len(array)) - 1
item = array[index]
if index == 0 : return item,item
subMin,subMax = minMax(array,index)
if item < subMin: return item,subMax
if item > subMax: return subMin,item
return subMin,subMax
Вы можете объединить два предыдущих всократить накладные расходы и избежать предела рекурсии, но при этом производительность немного снизится:
def minMax(array, start=0, end=None):
if end is None : end = len(array)-1
if start >= end - 1:
left,right = array[start],array[end]
return (left,right) if left < right else (right,left)
middle = (start + end) >> 1
leftMin,leftMax = minMax(array, start,middle)
rightMin,rightMax = minMax(array, middle+1,end)
return ( leftMin if leftMin < rightMin else rightMin ), \
( leftMax if leftMax > rightMax else rightMax )