Найдите самую длинную длину последовательности, сумма которой делится на 3

У меня есть упражнение, которое нужно выполнить с помощью временной сложности O (n), однако я могу решить его только с помощью решения O (n ^ 2).

У вас есть массив, и вам нужно подсчитать длинную непрерывную последовательность, чтобы сумма могла быть разделена на 3 без остатка. Например, для array {1,2,3,-4,-1) функция вернет 4, потому что самая длинная последовательность, которую ее sum(0) можно разделить на 3, равна {2,3,-4,-1}.

Мое решение O (n ^ 2) основано на arithmetic progression. Есть ли способ сделать это с помощью O (n) сложности?

Пожалуйста, мне нужна только подсказка или теоретическое объяснение. Пожалуйста, не пишите полное решение:)

Ответы

Ответ 1

Посмотрим на префиксные суммы. Подмарина [L, R] делится на 3 тогда и только тогда, когда
prefixSum[L - 1] mod 3 = prefixSum[R] mod 3. Это наблюдение дает очень простое линейное решение (потому что есть только 3 возможных значения префиксной суммы mod 3, мы можем просто найти первую и последнюю).

Например, если входной массив равен {1, 2, 3, -4, -1}, сумма префикса равна {0, 1, 0, 0, 2, 1}. (есть префиксы n + 1 из-за пустого префикса). Теперь вы можете просто взглянуть на первое и последнее вхождение 0, 1 и 2.

Ответ 2

Как человек, не относящийся к CS, это интересно. Первый мой подход был просто для вычисления текущей суммы мод 3. Вы получите последовательность {0,1,2}. Теперь найдите первый и последний 0, первый и последний 1, а первый и последний 2 и сравните их соответствующие расстояния...

Ответ 3

Итерации через массив, суммируя общее количество, как вы идете. Запишите положение первой позиции, где сумма по модулю 0. Также запишите положение первой позиции, где сумма по модулю 1. И, наконец, запишите положение первой позиции, где сумма по модулю 2.

Сделайте то же самое и назад, записывая последнюю позицию, где сумма по модулю 0, 1 и 2. Это дает три возможности для самой длинной последовательности - вы просто проверяете, какая пара находится на расстоянии друг от друга.

Ответ 4

Вы применяете динамическое программирование. Для каждой позиции вы вычисляете 3 значения:

  • Самая длинная последовательность, заканчивающаяся в этой позиции, которая имеет сумму s = 0 mod 3
  • Самая длинная последовательность, заканчивающаяся в этой позиции, которая имеет сумму s = 1 mod 3
  • Самая длинная последовательность, заканчивающаяся в этой позиции, которая имеет сумму s = 2 mod 3

Поэтому, учитывая это значение для позиции i, вы можете легко вычислить новые для позиции я + 1.