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: -1Input: 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
// C++ program to find the maximum sum // subsequence under given constraint #include <bits/stdc++.h> using namespace std; // Function return the maximum sum int ConstrainedSubsetSum(vector< int >& nums, int k) { deque<pair< int , int > > d; // Iterating the given array for ( int i = 0; i < nums.size(); i++) { // Check if deque is empty 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; } // Driver code int main() { vector< int > nums = { 10, -2, -10, -5, 20 }; int K = 2; // Function call cout << ConstrainedSubsetSum(nums, K) << endl; return 0; } |
Java
// Java program to find the maximum sum // subsequence under given constraint import java.io.*; import java.util.*; class GFG { // pair class static class pair { int first, second; public pair( int first, int second) { this .first = first; this .second = second; } } // Function to return the maximum sum static int ConstrainedSubsetSum( int [] nums, int k) { Deque<pair> d = new LinkedList<>(); // Iterating the given array for ( int i = 0 ; i < nums.length; i++) { // Check if deque is empty 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; } // Driver code public static void main(String[] args) { int [] nums = { 10 , - 2 , - 10 , - 5 , 20 }; int K = 2 ; // Function call System.out.print(ConstrainedSubsetSum(nums, K)); } } // This code is contributed by lokeshmvs21. |
Python3
# Python code from collections import deque def ConstrainedSubsetSum(nums, k): d = deque() # Iterating the given array 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 # Driver code nums = [ 10 , - 2 , - 10 , - 5 , 20 ] K = 2 print (ConstrainedSubsetSum(nums, K)) # This code is contributed by Utkarsh |
C#
using System; using System.Collections.Generic; class GFG { // pair class class Pair { public int First { get ; set ; } public int Second { get ; set ; } public Pair( int first, int second) { First = first; Second = second; } } // Function to return the maximum sum static int ConstrainedSubsetSum( int [] nums, int k) { LinkedList<Pair> d = new LinkedList<Pair>(); // Iterating the given array for ( int i = 0; i < nums.Length; i++) { // Check if deque is empty 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; } // Driver code public static void Main( string [] args) { int [] nums = { 10, -2, -10, -5, 20 }; int k = 2; // Function call Console.Write(ConstrainedSubsetSum(nums, k)); } } |
Javascript
// JS program to find the maximum sum // subsequence under given constralet // Function return the maximum sum function ConstrainedSubsetSum(nums, k) { let d = []; // Iterating the given array for (let i = 0; i < nums.length; i++) { // Check if deque is empty 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; } // Driver code let nums = [ 10, -2, -10, -5, 20 ]; let K = 2; // Function call console.log(ConstrainedSubsetSum(nums, K)); |
23
Time Complexity: O(N)
Auxiliary Space: O(K)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!