Найдите самую длинную длину последовательности, сумма которой делится на 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.