Задачка с собеседования от Яндекса. Скептически отношусь к ценности таких задачек при собеседовании сеньоров в обычный энтерпрайз - они скорее хороши на районном этапе школьной олимпиады. Но может я не прав? Итак задачка - из 4х предложенных над этой я думал дольше других:
В массиве целых чисел нужно найти фрагмент с заданной суммой.
Например, дан массив a = [4, 3, -8, 4, -1, 12, -5, 2]
и целевая сумма 5 - тогда ответом будет фрагмент начиная с 3
и заканчивая -5
, то есть в синтаксисе Питона sum(a[1:7]) = 5
В чем тут сложность? Сложность во "временной сложности" - требуется чтобы на массиве из миллиона чисел вычисление не занимало минуты. Поэтому наивный вариант не годится:
target = 5
for i in range(len(a)):
for j in range(i+1, len(a)+1):
if sum(a[i:j]) == target:
print(i, j)
Здесь два вложенных цикла - каждый в среднем совершает число итераций сравнимое с длиной массива. Но функция sum(...)
внутри тоже бежит по массиву - итого время выполнения пропорционально длине массива в кубе O(N*N*N)
Одно из усовершенствований заключается в том чтобы построить второй массив, в котором хранить сумму от начала массива до i-го
элемента. Это позволит считать sum(i, j)
не пробегая массив. Улучшение - теперь время пропорционально квадрату.
Можно решить и за "линейное" время - т.е. пропорциональное размеру массива без всякой степени. Когда я сообразил, то сказал "да это же старая задачка на новый лад". Попробуйте - вдруг пригодится на собесе :)