Задача о поиске всех подходящих под-сум

№560 leetcode Subarray Sum Equals K.

Есть массив чисел, и дано значение k. Надо найти все последовательные под-массивы сумма которых равна k.

В условиях также сказано, что числа в массиве могут быть как положительные, так и отрицательные. Если бы мы имели дело с числами с одинаковым знаком, то задача решалась бы с использованием скользящего окна. Но здесь надо искать какой то более общий подход.

Решение «в лоб» понятное и простое — мы перебираем все под-массивы, при этом можно оптимизировать перебор, накапливая сумму в цикле. Выглядит это так:

Сложность, как видите, n^2.

Eсть и более производительное решение, которое не очень было понятно для меня, потому я его разберу подробнее.

По сути мы имеем дело с обнаружением величины k.

Это сумма некоторого под-массива, который начинается с индекса i и заканчивается индексом j. Мы можем выразить k через разницу между двумя суммами Σj и Σi. Где сумма Σx — это сумма всех элементов с начала массива до элемента с номером x.

Σj — Σi = k. (1)

Это идея позволяет нам реализовать следующий алгоритм.

Мы суммируем элементы массива последовательно в цикле, получая Σj — сумму элементов до рассматриваемого элемента, таким образом мы получаем все значения Σx, среди которых Σj и Σi.

На каждой итерации мы делаем три вещи:

  1. Очевидно, что надо проверить не равна ли текущая сумма k. Σx == k — один из искомых кейсов.
  2. Менее очевидно то, что надо проверить сколько раз мы уже набирали Σx = (Σj — k)
  3. Запоминаем сколько раз мы набрали Σj, формируя набор Σi.

Что мы делаем во 2ом пункте? Если на текущей итерации оказывается, что мы уже набирали сумму равную Σj — k, то именно столько под-массивов нужно добавить к текущему результату. Т.к. из формулы (1) следует, что

Σj — k = Σi (2)

И именно это нужно проверить.

Мало букафф? Читайте есчо !

Задача - число островов

Март 25, 2023 г.

Разбираю задачу #200 с литкода, число островов (number of islands). Задан двумерный массив, в котором участки суши помечены как "1", а участки воды - как "0". Требуется подсчитать число получившихся островов. При этом считается, что участки суши образуют ...

Читать

Задача о последнем дне переправы по льду

Июнь 30, 2023 г.

Задачу можно сформулировать так: представьте себе участок реки покрытый льдом и в первый день он полностью скован крепким льдом, позволяющим переправится ...

Читать

Игра в камни

Май 27, 2023 г.

Серия задач StoneGame на leetcode - образец игры, где требуется просчитать оптимальную стратегию. Выигрыш/проигрыш начинающего партию предопределен, и второй участник лишь может надеяться на ошибку первого. Но это не наш случай, т.к. по условию ...

Читать

Поиск выхода из лабиринта

Июнь 3, 2023 г.

Продолжаем разбор классических задач по программированию. На этот раз лабиринтовая задача, которая формулируется так - дан плоский лабиринт в виде двумерного массива, где стенка отмечена 1, а свободный участок как 0. Также дана начальная позиция игрока, ...

Читать
 

Комментарии к «Задача о поиске всех подходящих под-сум»

Понравилась статья? Есть вопросы? - пишите в комментариях.



Комментарий: