Maximum sum of subarrays having distinct elements of length K
Last Updated :
28 Feb, 2023
Given an array, arr[] and a value k, represent the length of the subarray to be considered. Find the maximum sum that can be obtained from the subarray of length k such that each element of the subarray is unique. If there is no subarray that meets the required condition then return 0.
Examples:
Input: arr[] = {1, 5, 4, 2, 9, 9, 9}, k = 3
Output: 15
Explanation: The possible subarrays of arr 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 element 9 is repeated.
- {9, 9, 9} which does not meet the requirements because element 9 is repeated.
We return 15 because it is the maximum subarray sum of all the subarrays that meet the condition.
Input: arr[] = {4, 4, 4}, k = 3
Output: 0
Explanation: The subarrays of arr with length 3 is {4, 4, 4} which does not meet the requirements because element 4 is repeated.
We return 0 because no subarrays meet the conditions.
Approach: The problem can be solved based on the following idea:
The idea is based on two pointer Algorithm, where we will fix the size of the subarray k. Iterate over the array if the size of the map becomes equal to k, Update the maximum sum if required.
Follow the below steps to implement the idea:
- Take a map data structure that will store the elements of the subarray.
- Take two variables currentSum which will store the sum of the current subarray and maxSum which will store the max sum of the subarray present in the given array.
- Take a variable left that will point to the leftmost index of the element of the subarray considered.
- Iterate the array and perform the following step in each iteration:-
- Add the current element of the subarray in the map.
- Decrease the frequency of the left element of the subarray from the map. If the frequency of the leftmost element of the subarray is zero then remove that element from the map.
- Subtract the leftMost element of the subarray from the currentSum.
- Add the value of the current element in the currentSum.
- If the size of the map is equal to k then (which means that all the elements present in the map are unique and hence all the elements of the subarray considered are unique and hence this subarray will be considered) take the max value of currentSum and maxSum.
- Increment the left value by 1.
Below is the implementation of the above algorithm:-
C++
#include <bits/stdc++.h>
using namespace std;
int helper(vector< int >& arr, int k)
{
unordered_map< int , int > mp;
int currentSum = 0, maxSum = 0;
int n = arr.size(), left = 0, i = 0;
while (i < k && i < n) {
currentSum += arr[i];
mp[arr[i]]++;
i++;
}
if (mp.size() == k) {
maxSum = currentSum;
}
for ( int i = k; i < n; i++) {
mp[arr[i]]++;
mp[arr[left]]--;
if (mp[arr[left]] == 0) {
mp.erase(arr[left]);
}
currentSum += arr[i];
currentSum -= arr[left];
if (mp.size() == k) {
maxSum = max(maxSum, currentSum);
}
++left;
}
return maxSum;
}
int main()
{
vector< int > arr = { 1, 5, 4, 2, 9, 9, 9 };
int k = 3;
cout << helper(arr, k);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int helper( int [] arr, int k) {
HashMap<Integer,Integer> mp = new HashMap<Integer,Integer>();
int currentSum = 0 , maxSum = 0 ;
int n = arr.length, left = 0 , i = 0 ;
while (i < k && i < n) {
currentSum += arr[i];
if (mp.containsKey(arr[i]))
mp.put(arr[i], mp.get(arr[i]) + 1 );
else
mp.put(arr[i], 1 );
i++;
}
if (mp.size() == k) {
maxSum = currentSum;
}
for ( i = k; i < n; i++) {
if (mp.containsKey(arr[i]))
mp.put(arr[i], mp.get(arr[i]) + 1 );
else
mp.put(arr[i] , 1 );
if (mp.containsKey(arr[left])) {
mp.put(arr[left], mp.get(arr[left]) - 1 );
if (mp.get(arr[left]) <= 0 ) {
mp.remove(arr[left]);
}
currentSum += arr[i];
currentSum -= arr[left];
if (mp.size() == k) {
maxSum = Math.max(maxSum, currentSum);
}
left++;
}
}
return maxSum;
}
public static void main(String[] args) {
int [] arr = { 1 , 5 , 4 , 2 , 9 , 9 , 9 };
int k = 3 ;
System.out.println(helper(arr, k));
}
}
|
Python3
from collections import defaultdict
def helper(arr, k):
mp = defaultdict( int )
currentSum = 0
maxSum = 0
n = len (arr)
left = 0
i = 0
while i < k and i < n:
currentSum + = arr[i]
mp[arr[i]] + = 1
i + = 1
if len (mp) = = k:
maxSum = currentSum
for i in range (k, n):
mp[arr[i]] + = 1
mp[arr[left]] - = 1
if mp[arr[left]] = = 0 :
del mp[arr[left]]
currentSum + = arr[i]
currentSum - = arr[left]
if len (mp) = = k:
maxSum = max (maxSum, currentSum)
left + = 1
return maxSum
if __name__ = = "__main__" :
arr = [ 1 , 5 , 4 , 2 , 9 , 9 , 9 ]
k = 3
print (helper(arr, k))
|
C#
using System;
using System.Collections.Generic;
class Gfg
{
static int helper(List< int > arr, int k)
{
Dictionary< int , int > mp= new Dictionary< int , int >();
int currentSum = 0, maxSum = 0;
int n = arr.Count, left = 0, i = 0;
while (i < k && i < n) {
currentSum += arr[i];
if (mp.ContainsKey(arr[i]))
{
var val = mp[arr[i]];
mp.Remove(arr[i]);
mp.Add(arr[i], val + 1);
}
else
{
mp.Add(arr[i], 1);
}
i++;
}
if (mp.Count == k) {
maxSum = currentSum;
}
for ( i = k; i < n; i++)
{
if (mp.ContainsKey(arr[i]))
{
var val = mp[arr[i]];
mp.Remove(arr[i]);
mp.Add(arr[i], val + 1);
}
else
mp.Add(arr[i], 1);
if (mp.ContainsKey(arr[left]))
{
var val = mp[arr[left]];
mp.Remove(arr[left]);
mp.Add(arr[left], val -1);
}
if (mp.ContainsKey(arr[left]) && mp[arr[left]] == 0) {
mp.Remove(arr[left]);
}
currentSum += arr[i];
currentSum -= arr[left];
if (mp.Count == k) {
maxSum = Math.Max(maxSum, currentSum);
}
left++;
}
return maxSum;
}
public static void Main( string [] args)
{
List< int > arr = new List< int >{ 1, 5, 4, 2, 9, 9, 9 };
int k = 3;
Console.Write(helper(arr, k));
}
}
|
Javascript
<script>
function findMaxSum(arr, k) {
const elementCounts = new Map();
let currentSum = 0;
let maxSum = 0;
const n = arr.length;
let left = 0;
let i = 0;
while (i < k && i < n) {
currentSum += arr[i];
elementCounts.set(arr[i], (elementCounts.get(arr[i]) || 0) + 1);
i++;
}
if (elementCounts.size === k) {
maxSum = currentSum;
}
for (let i = k; i < n; i++) {
elementCounts.set(arr[i], (elementCounts.get(arr[i]) || 0) + 1);
elementCounts.set(arr[left], elementCounts.get(arr[left]) - 1);
if (elementCounts.get(arr[left]) === 0) {
elementCounts. delete (arr[left]);
}
currentSum += arr[i];
currentSum -= arr[left];
if (elementCounts.size === k) {
maxSum = Math.max(maxSum, currentSum);
}
left++;
}
return maxSum;
}
const arr = [1, 5, 4, 2, 9, 9, 9];
const k = 3;
document.write(findMaxSum(arr, k));
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(k)
Another Approach: Sliding window technique
- Start by initializing variables and arrays: a)Initialize integer variables n, i, j, ans, and sum to 0.
b)Initialize an integer array freq of size 100001 to 0.
- Iterate over the array using two pointers i and j: a)At each iteration, add the jth element to freq and sum.
b)Check if the subarray between i and j is of length k.
- If the subarray is of length k, check if all elements in the subarray are distinct: a)Iterate over the frequency array freq from 0 to 100000.
b)If any element occurs more than once, set distinct to false.
- If all elements in the subarray are distinct, update the answer ans: a)Set ans to the maximum of ans and sum.
- Remove the ith element from freq and sum: a)Decrement freq[nums[i]].
b)Subtract nums[i] from sum.
- Move the pointers i and j ahead: a)Increment i and j by 1.
- If the subarray is not of length k, increase the length: a)Increment j by 1.
- Continue iterating until the end of the array is reached.
- Return the answer ans.
Below is the implementation of above algorithm:-
C++
#include<bits/stdc++.h>
using namespace std;
int maxSum(vector< int >& nums, int k){
int n = nums.size(), i = 0, j = 0, ans = 0, sum = 0;
int freq[100001] = {0};
while (j < n){
freq[nums[j]]++;
sum += nums[j];
if (j - i + 1 == k){
bool distinct = true ;
for ( int x = 0; x <= 100000; x++){
if (freq[x] > 1){
distinct = false ;
break ;
}
}
if (distinct){
ans = max(ans, sum);
}
freq[nums[i]]--;
sum -= nums[i];
i++; j++;
}
else {
j++;
}
}
return ans;
}
int main(){
vector< int > nums = {1, 5, 4, 2, 9, 9, 9};
int k = 3;
cout<<maxSum(nums,k)<<endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int maxSum(List<Integer> nums, int k) {
int n = nums.size(), i = 0 , j = 0 , ans = 0 , sum = 0 ;
int [] freq = new int [ 100001 ];
while (j < n) {
freq[nums.get(j)]++;
sum += nums.get(j);
if (j - i + 1 == k) {
boolean distinct = true ;
for ( int x = 0 ; x <= 100000 ; x++) {
if (freq[x] > 1 ) {
distinct = false ;
break ;
}
}
if (distinct) {
ans = Math.max(ans, sum);
}
freq[nums.get(i)]--;
sum -= nums.get(i);
i++; j++;
}
else {
j++;
}
}
return ans;
}
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>(Arrays.asList( 1 , 5 , 4 , 2 , 9 , 9 , 9 ));
int k = 3 ;
System.out.println(maxSum(nums, k));
}
}
|
C#
using System;
using System.Collections.Generic;
public class Program
{
public static int maxSum(List< int > nums, int k)
{
int n = nums.Count, i = 0, j = 0, ans = 0, sum = 0;
int [] freq = new int [100001];
while (j < n)
{
freq[nums[j]]++;
sum += nums[j];
if (j - i + 1 == k)
{
bool distinct = true ;
for ( int x = 0; x <= 100000; x++)
{
if (freq[x] > 1)
{
distinct = false ;
break ;
}
}
if (distinct)
{
ans = Math.Max(ans, sum);
}
freq[nums[i]]--;
sum -= nums[i];
i++; j++;
}
else
{
j++;
}
}
return ans;
}
public static void Main()
{
List< int > nums = new List< int >( new int [] { 1, 5, 4, 2, 9, 9, 9 });
int k = 3;
Console.WriteLine(maxSum(nums, k));
}
}
|
Python3
def max_sum(nums, k):
n = len (nums)
i, j, ans, s = 0 , 0 , 0 , 0
freq = [ 0 ] * 100001
while j < n:
freq[nums[j]] + = 1
s + = nums[j]
if j - i + 1 = = k:
distinct = True
for x in range ( 100001 ):
if freq[x] > 1 :
distinct = False
break
if distinct:
ans = max (ans, s)
freq[nums[i]] - = 1
s - = nums[i]
i + = 1
j + = 1
else :
j + = 1
return ans
nums = [ 1 , 5 , 4 , 2 , 9 , 9 , 9 ]
k = 3
print (max_sum(nums, k))
|
Javascript
function maxSum(nums, k) {
const n = nums.length;
let i = 0, j = 0, ans = 0, sum = 0;
const freq = new Array(100001).fill(0);
while (j < n) {
freq[nums[j]]++;
sum += nums[j];
if (j - i + 1 == k) {
let distinct = true ;
for (let x = 0; x <= 100000; x++) {
if (freq[x] > 1) {
distinct = false ;
break ;
}
}
if (distinct) {
ans = Math.max(ans, sum);
}
freq[nums[i]]--;
sum -= nums[i];
i++; j++;
} else {
j++;
}
}
return ans;
}
const nums = [1, 5, 4, 2, 9, 9, 9];
const k = 3;
console.log(maxSum(nums, k));
|
Time Complexity: O(n*k)
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...