Find maximum Subsequence Sum according to given conditions
Given an integer array nums and an integer K, The task is to find the maximum sum of a non-empty subsequence of the array such that for every two consecutive integers in the subsequence, nums[i] and nums[j], where i < j, the condition j – i <= K is satisfied.
A subsequence of an array is obtained by deleting some number of elements (can be zero) from the array, leaving the remaining elements in their original order.
Examples:
Input: nums = [10, 2, -10, 5, 20], K = 2
Output: 37
Explanation: The subsequence is [10, 2, 5, 20].
Input: nums = [-1, -2, -3], K = 1
Output: -1
Input: nums = [10, -2, -10, -5, 20], K = 2
Output: 23
Approach:
- The optimal solution of this problem can be achieved by using the Sliding Window Maximum and Dynamic Programming .
- At any index i after calculating the maximum sum for i, nums[i] will now store the maximum possible sum that can be obtained from a subsequence ending at i.
- To calculate the maximum possible sum for every index i , check what is the maximum value that can be obtained from a window of size K before it. If the maximum value is negative, use zero instead.
- To use the values of calculated sums optimally we use a deque to store the sums along with their indexes in an increasing order of the sums . We also pop the element from the back when its index goes out of the window k of current index i.
CPP
#include <bits/stdc++.h>
using namespace std;
int ConstrainedSubsetSum(vector< int >& nums,
int k)
{
deque<pair< int , int > > d;
for ( int i = 0; i < nums.size(); i++)
{
nums[i] += d.size()
? max(d.back().first, 0) : 0;
while (d.size() &&
d.front().first < nums[i])
d.pop_front();
d.push_front({ nums[i], i });
if (d.back().second == i - k)
d.pop_back();
}
int ans = nums[0];
for ( auto x : nums)
ans = max(ans, x);
return ans;
}
int main()
{
vector< int > nums = { 10, -2, -10,
-5, 20 };
int K = 2;
cout << ConstrainedSubsetSum(nums, K)
<< endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static class pair {
int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
static int ConstrainedSubsetSum( int [] nums, int k)
{
Deque<pair> d = new LinkedList<>();
for ( int i = 0 ; i < nums.length; i++) {
nums[i]
+= (d.size() != 0
? Math.max(d.peekLast().first, 0 )
: 0 );
while (d.size() != 0
&& d.peekFirst().first < nums[i]) {
d.removeFirst();
}
d.offerFirst( new pair(nums[i], i));
if (d.peekLast().second == i - k) {
d.removeLast();
}
}
int ans = nums[ 0 ];
for ( int i = 0 ; i < nums.length; i++) {
ans = Math.max(ans, nums[i]);
}
return ans;
}
public static void main(String[] args)
{
int [] nums = { 10 , - 2 , - 10 , - 5 , 20 };
int K = 2 ;
System.out.print(ConstrainedSubsetSum(nums, K));
}
}
|
Python3
from collections import deque
def ConstrainedSubsetSum(nums, k):
d = deque()
for i in range ( len (nums)):
nums[i] + = d[ - 1 ][ 0 ] if d and d[ - 1 ][ 0 ] > 0 else 0
while d and d[ 0 ][ 0 ] < nums[i]:
d.popleft()
d.appendleft((nums[i], i))
if d and d[ - 1 ][ 1 ] = = i - k:
d.pop()
ans = nums[ 0 ]
for i in range ( 1 , len (nums)):
ans = max (ans,nums[i])
return ans
nums = [ 10 , - 2 , - 10 , - 5 , 20 ]
K = 2
print (ConstrainedSubsetSum(nums, K))
|
C#
using System;
using System.Collections.Generic;
class GFG {
class Pair {
public int First { get ; set ; }
public int Second { get ; set ; }
public Pair( int first, int second) {
First = first;
Second = second;
}
}
static int ConstrainedSubsetSum( int [] nums, int k) {
LinkedList<Pair> d = new LinkedList<Pair>();
for ( int i = 0; i < nums.Length; i++) {
nums[i] += (d.Count != 0 ? Math.Max(d.Last.Value.First, 0) : 0);
while (d.Count != 0 && d.First.Value.First < nums[i]) {
d.RemoveFirst();
}
d.AddFirst( new Pair(nums[i], i));
if (d.Last.Value.Second == i - k) {
d.RemoveLast();
}
}
int ans = nums[0];
foreach (Pair pair in d) {
ans = Math.Max(ans, pair.First);
}
return ans;
}
public static void Main( string [] args) {
int [] nums = { 10, -2, -10, -5, 20 };
int k = 2;
Console.Write(ConstrainedSubsetSum(nums, k));
}
}
|
Javascript
function ConstrainedSubsetSum(nums, k)
{
let d = [];
for (let i = 0; i < nums.length; i++)
{
nums[i] += d.length
? Math.max(d[d.length - 1][0], 0) : 0;
while (d.length &&
d[0][0] < nums[i])
d.shift();
d.unshift([nums[i], i]);
if (d[d.length - 1][1] === i - k)
d.pop();
}
let ans = nums[0];
for (let x of nums)
ans = Math.max(ans, x);
return ans;
}
let nums = [ 10, -2, -10, -5, 20 ];
let K = 2;
console.log(ConstrainedSubsetSum(nums, K));
|
Time Complexity: O(N)
Auxiliary Space: O(K)
Last Updated :
29 Aug, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...