1425. Constrained Subsequence Sum
Дан entier tableau nums и entier k, return максимальную сумму непустой подпоследовательности этого tableauа, такую, что для любых двух последовательных целых чисел в подпоследовательности nums[i] и nums[j], где i < j, выполняется Énoncé j - i <= k.
subsequence tableauа получается путем удаления некоторого количества elementов (может быть ноль) из tableauа, оставляя оставшиеся elementы в их исходном порядке.
Exemple:
Input: nums = [10,2,-10,5,20], k = 2
Output: 37
Explanation: The subsequence is [10, 2, 5, 20].
C# solution
correspondant/originalpublic 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;
}
}
C++ solution
brouillon automatique, à relire avant soumission#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
public int ConstrainedSubsetSum(vector<int>& nums, int k) {
Deque<int> queue = new LinkedList<int>();
vector<int>& dp = new int[nums.size()];
int maxSum = int.MinValue;
for (int i = 0; i < nums.size(); i++) {
if (queue.size() > 0 && i - queue.First.Value > k) {
queue.RemoveFirst();
}
dp[i] = (queue.size() > 0 ? dp[queue.First.Value] : 0) + nums[i];
while (queue.size() > 0 && dp[queue.Last.Value] < dp[i]) {
queue.RemoveLast();
}
if (dp[i] > 0) {
queue.AddLast(i);
}
maxSum = max(maxSum, dp[i]);
}
return maxSum;
}
}
Java solution
correspondant/originalclass Solution {
public int constrainedSubsetSum(int[] nums, int k) {
Deque<Integer> queue = new ArrayDeque<>();
int dp[] = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
if (!queue.isEmpty() && i - queue.peek() > k) {
queue.poll();
}
dp[i] = (!queue.isEmpty() ? dp[queue.peek()] : 0) + nums[i];
while (!queue.isEmpty() && dp[queue.peekLast()] < dp[i]) {
queue.pollLast();
}
if (dp[i] > 0) {
queue.offer(i);
}
}
int ans = Integer.MIN_VALUE;
for (int num : dp) {
ans = Math.max(ans, num);
}
return ans;
}
}
JavaScript solution
correspondant/originalclass Solution {
constrainedSubsetSum(nums, k) {
const queue = [];
const dp = new Array(nums.length).fill(0);
let maxSum = Number.MIN_SAFE_INTEGER;
for (let i = 0; i < nums.length; i++) {
if (queue.length > 0 && i - queue[0] > k) {
queue.shift();
}
dp[i] = (queue.length > 0 ? dp[queue[0]] : 0) + nums[i];
while (queue.length > 0 && dp[queue[queue.length - 1]] < dp[i]) {
queue.pop();
}
if (dp[i] > 0) {
queue.push(i);
}
maxSum = Math.max(maxSum, dp[i]);
}
return maxSum;
}
}
Go solution
correspondant/originalfunc constrainedSubsetSum(nums []int, k int) int {
queue := []int{}
dp := make([]int, len(nums))
maxSum := nums[0]
for i := 0; i < len(nums); i++ {
if len(queue) > 0 && i - queue[0] > k {
queue = queue[1:]
}
if len(queue) > 0 {
dp[i] = dp[queue[0]] + nums[i]
} else {
dp[i] = nums[i]
}
for len(queue) > 0 && dp[queue[len(queue) - 1]] < dp[i] {
queue = queue[:len(queue) - 1]
}
if dp[i] > 0 {
queue = append(queue, i)
}
if dp[i] > maxSum {
maxSum = dp[i]
}
}
return maxSum
}
Algorithm
Инициализируйте очередь queue и tableau dp той же длины, что и nums.
Итерируйте i по индексам nums:
Если i минус первый element queue больше k, удалите element из начала queue.
Установите dp[i] как dp[queue.front()] + nums[i]. Если queue пуст, используйте 0 вместо dp[queue.front()].
Пока dp[queue.back()] меньше dp[i], удаляйте elementы с конца queue.
Если dp[i] > 0, добавьте i в конец queue.
return максимальное значение в tableauе dp.
😎
Vacancies for this task
offres actives with overlapping task tags are affichés.