Maximum Sum of Distinct Subarrays With Length K
MEDIUMDescription
You are given an integer array nums and an integer k. Find the maximum subarray sum of all the subarrays of nums that meet the following conditions:
- The length of the subarray is
k, and - All the elements of the subarray are distinct.
Return the maximum subarray sum of all the subarrays that meet the conditions. If no subarray meets the conditions, return 0.
A subarray is a contiguous non-empty sequence of elements within an array.
Example 1:
Input: nums = [1,5,4,2,9,9,9], k = 3 Output: 15 Explanation: The subarrays of nums with length 3 are: - [1,5,4] which meets the requirements and has a sum of 10. - [5,4,2] which meets the requirements and has a sum of 11. - [4,2,9] which meets the requirements and has a sum of 15. - [2,9,9] which does not meet the requirements because the element 9 is repeated. - [9,9,9] which does not meet the requirements because the element 9 is repeated. We return 15 because it is the maximum subarray sum of all the subarrays that meet the conditions
Example 2:
Input: nums = [4,4,4], k = 3 Output: 0 Explanation: The subarrays of nums with length 3 are: - [4,4,4] which does not meet the requirements because the element 4 is repeated. We return 0 because no subarrays meet the conditions.
Constraints:
1 <= k <= nums.length <= 1051 <= nums[i] <= 105
Approaches
Checkout 2 different approaches to solve Maximum Sum of Distinct Subarrays With Length K. Click on different approaches to view the approach and algorithm in detail.
Sliding Window with Frequency Map
This approach uses a sliding window of size k to efficiently calculate the sum and check for distinct elements. By sliding the window one element at a time, we can update the sum and element counts in constant time on average, avoiding recalculation.
Algorithm
- Initialize
maxSum = 0L,currentSum = 0L, and aHashMap<Integer, Integer> freqMapto store element frequencies in the current window. - Iterate through the
numsarray with indexifrom0ton-1. - Add element to window: Add
nums[i]tocurrentSumand increment its count infreqMap. - Maintain window size: If
i >= k, the window is now of sizek+1. We must remove the leftmost element,nums[i-k], to shrink it back to sizek.- Subtract
nums[i-k]fromcurrentSum. - Decrement the count of
nums[i-k]infreqMap. - If the count of
nums[i-k]becomes 0, remove it from the map to keep the map size accurate for the distinctness check.
- Subtract
- Check for valid subarray: If the window has reached size
k(i.e.,i >= k-1), check if it meets the distinctness condition.- The condition is met if
freqMap.size() == k. - If it is met, update
maxSum = Math.max(maxSum, currentSum).
- The condition is met if
- After the loop finishes, return
maxSum.
This optimized approach avoids the redundant work of the brute-force method by using a sliding window. The window is a conceptual frame of size k that moves across the array one element at a time. We maintain the sum of elements and their frequencies within the current window.
We use a HashMap to store the frequency of each number in the window. A key property we use is that a window of k elements has all distinct numbers if and only if the number of unique keys in our frequency map is exactly k.
The process begins by iterating through the array. For each element, we add it to our window. Once the window reaches size k, we check if it's a valid subarray. Then, for all subsequent elements, we "slide" the window by:
- Adding the new element from the right to our sum and frequency map.
- Removing the leftmost element (which is now outside the window) from our sum and frequency map.
After each slide, we check if the map's size is k. If it is, we have a valid subarray, and we update our maximum sum. This way, each element of the input array is processed only a constant number of times, leading to a linear time complexity.
import java.util.HashMap;
import java.util.Map;
class Solution {
public long maximumSubarraySum(int[] nums, int k) {
long maxSum = 0;
long currentSum = 0;
Map<Integer, Integer> freqMap = new HashMap<>();
int n = nums.length;
for (int i = 0; i < n; i++) {
// Add the current element to the window
currentSum += nums[i];
freqMap.put(nums[i], freqMap.getOrDefault(nums[i], 0) + 1);
// If window size is now greater than k, remove the leftmost element
if (i >= k) {
int leftElement = nums[i - k];
currentSum -= leftElement;
freqMap.put(leftElement, freqMap.get(leftElement) - 1);
if (freqMap.get(leftElement) == 0) {
freqMap.remove(leftElement);
}
}
// Check if the current window is valid (size k and all distinct)
if (i >= k - 1) {
if (freqMap.size() == k) {
maxSum = Math.max(maxSum, currentSum);
}
}
}
return maxSum;
}
}
Complexity Analysis
Pros and Cons
- Highly efficient with O(n) time complexity, making it suitable for large inputs.
- Optimal solution for the given constraints.
- Slightly more complex to implement compared to the brute-force approach.
- Requires extra space for the frequency map, which could be O(k).
Code Solutions
Checking out 4 solutions in different languages for Maximum Sum of Distinct Subarrays With Length K. Click on different languages to view the code.
public class Solution {
public long MaximumSubarraySum(int[] nums, int k) {
int n = nums.Length;
Dictionary < int, int > cnt = new Dictionary < int, int > (k);
long s = 0;
for (int i = 0; i < k; ++i) {
if (!cnt.ContainsKey(nums[i])) {
cnt[nums[i]] = 1;
} else {
cnt[nums[i]]++;
}
s += nums[i];
}
long ans = cnt.Count == k ? s : 0;
for (int i = k; i < n; ++i) {
if (!cnt.ContainsKey(nums[i])) {
cnt[nums[i]] = 1;
} else {
cnt[nums[i]]++;
}
if (--cnt[nums[i - k]] == 0) {
cnt.Remove(nums[i - k]);
}
s += nums[i] - nums[i - k];
if (cnt.Count == k) {
ans = Math.Max(ans, s);
}
}
return ans;
}
}Video Solution
Watch the video walkthrough for Maximum Sum of Distinct Subarrays With Length K
Similar Questions
5 related questions you might find useful
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.