Given an integer array nums and an integer k, return the maximum sum of a non-empty subsequence of that 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.
Input:
nums =[10,2,-10,5,20], k =2Output: 37Explanation: The subsequence is[10,2,5,20].The possible subsequences satisfying the conditions are:-[10,2]with sum 12-[10,2,5]with sum 17-[10,2,5,20]with sum 37-[10,5,20]with sum 35-[2,5,20]with sum 27Among these, the subsequence [10,2,5,20] has the maximum sum of 37.
Example 2:
1
2
3
4
Input:
nums =[-1,-2,-3], k =1Output: -1Explanation: The subsequence must be non-empty, so we choose the largest number.
Example 3:
1
2
3
4
Input:
nums =[10,-2,-10,-5,20], k =2Output: 23Explanation: The subsequence is[10,-2,-5,20].
Initialisation: Create an array dp where dp[i] represents the maximum sum of a subsequence ending at index i. The result is initialised with the values of the nums array since the minimum subsequence ending at each index is the element itself.
Deque for Sliding Window Maximum: Use a deque to keep track of indices where dp values are potential candidates for forming a valid subsequence ending at a current element.
Iterate through the Array: For each element in nums, update dp[i] by considering the maximum dp[j] where i - k <= j < i.
Update Deque: Maintain the deque in such a way that the values in dp are in decreasing order. If the current index i makes the oldest value in the deque invalid (i.e., i - k > j), remove it from the deque.
Compute the Result: The result is the maximum value in the dp array.
import java.util.Deque;
import java.util.LinkedList;
classSolution {
publicintconstrainedSubsetSum(int[] nums, int k) {
int n = nums.length;
if (n == 0)
return 0;
// Initialize dp arrayint[] dp =newint[n];
System.arraycopy(nums, 0, dp, 0, n);
// Deque to store indices of potential maximums for dp array Deque<Integer> deque =new LinkedList<>();
for (int i = 0; i < n; i++) {
// Remove elements not within sliding window of size kwhile (!deque.isEmpty() && deque.peekFirst() < i - k) {
deque.pollFirst();
}
// Update dp[i] using the maximum value in dp[deque]if (!deque.isEmpty()) {
dp[i]+= dp[deque.peekFirst()];
}
// Maintain deque: remove elements from the deque that are smaller// than current dp[i]while (!deque.isEmpty() && dp[deque.peekLast()]<= dp[i]) {
deque.pollLast();
}
// Add current index to the deque deque.offerLast(i);
}
// The result is the maximum value in dp arrayint result = dp[0];
for (int i = 1; i < n; i++) {
result = Math.max(result, dp[i]);
}
return result;
}
publicstaticvoidmain(String[] args) {
Solution sol =new Solution();
int[] nums = {10, 2, -10, 5, 20};
int k = 2;
System.out.println(sol.constrainedSubsetSum(
nums, k)); // Output should be 37 (subsequence [10, 2, 5, 20]) }
}
classSolution:
defconstrainedSubsetSum(self, nums: List[int], k: int) -> int:
n = len(nums)
if n ==0:
return0# Initialize dp array dp = nums[:]
# Deque to store indices of potential maximums for dp array dq = deque()
for i in range(n):
# Remove elements not within sliding window of size kwhile dq and dq[0] < i - k:
dq.popleft()
# Update dp[i] using the maximum value in dp[dq]if dq:
dp[i] += dp[dq[0]]
# Maintain deque: remove elements from the deque that are smaller than current dp[i]while dq and dp[dq[-1]] <= dp[i]:
dq.pop()
# Add current index to the deque dq.append(i)
# The result is the maximum value in dp arrayreturn max(dp)