O (n) решение для списка положительных чисел
Если ваш список не может содержать отрицательные числа , тогда существует линейное решение с использованием обхода двумя указателями.
Отслеживание суммы между обоими указателями. Увеличивайте правый указатель всякий раз, когда сумма меньше 50, и увеличивайте левый в противном случае.
Это обеспечивает последовательность указателей, в пределах которых вы найдете те с минимальным расстоянием. Достаточно использовать min
, чтобы получить наименьший интервал из них.
Из-за поведения min
это вернет крайний левый подсписок с минимальной длиной, если существует более одного решения.
код
def intervals_generator(lst, bound):
i, j = 0, 0
sum_ = 0
while True:
try:
if sum_ <= bound:
sum_ += lst[j]
j += 1
else:
yield i, j
sum_ -= lst[i]
i += 1
except IndexError:
break
def smallest_sub_list(lst, bound):
i, j = min(intervals_generator(lst, bound), key=lambda x: x[1] - x[0])
return lst[i:j]
Примеры
lst = [8.4 , 10.3 , 12.9 , 8.2 , 13.7 , 11.2 , 11.3 ,10.4 , 4.2 , 3.3 , 4.0 , 2.1]
print(smallest_sub_list(lst, 50)) # [8.4, 10.3, 12.9, 8.2, 13.7]
lst = [0, 10, 45, 55]
print(smallest_sub_list(lst, 50)) # [55]
Решение для общего списка номеров
Если список может содержать отрицательные числа, то вышеприведенное не будет работать , и я считаю, что не существует более эффективного решения, чем перебирать все возможные подсписки.