Сложность: hard
Дан целочисленный массив nums и целое число k, верните максимальную сумму непустой подпоследовательности этого массива, такую, что для любых двух последовательных целых чисел в подпоследовательности nums[i] и nums[j], где i < j, выполняется условие j - i <= k.
Подпоследовательность массива получается путем удаления некоторого количества элементов (может быть ноль) из массива, оставляя оставшиеся элементы в их исходном порядке.
Пример:
Input: nums = [10,2,-10,5,20], k = 2
Output: 37
Explanation: The subsequence is [10, 2, 5, 20].
👨💻 Алгоритм:
1⃣Инициализируйте очередь queue и массив dp той же длины, что и nums.
2⃣Итерируйте i по индексам nums:
Если i минус первый элемент queue больше k, удалите элемент из начала queue.
Установите dp[i] как dp[queue.front()] + nums[i]. Если queue пуст, используйте 0 вместо dp[queue.front()].
Пока dp[queue.back()] меньше dp[i], удаляйте элементы с конца queue.
Если dp[i] > 0, добавьте i в конец queue.
3⃣Верните максимальное значение в массиве dp.
😎 Решение:
public class Solution {
public int ConstrainedSubsetSum(int[] nums, int k) {
Deque<int> queue = new LinkedList<int>();
int[] dp = new int[nums.Length];
int maxSum = int.MinValue;
for (int i = 0; i < nums.Length; i++) {
if (queue.Count > 0 && i - queue.First.Value > k) {
queue.RemoveFirst();
}
dp[i] = (queue.Count > 0 ? dp[queue.First.Value] : 0) + nums[i];
while (queue.Count > 0 && dp[queue.Last.Value] < dp[i]) {
queue.RemoveLast();
}
if (dp[i] > 0) {
queue.AddLast(i);
}
maxSum = Math.Max(maxSum, dp[i]);
}
return maxSum;
}
}Ставь 👍 и забирай 📚 Базу знаний