Maximum sum of K-length subarray consisting of same number of distinct elements as the given array
Last Updated :
29 Dec, 2022
Given an array arr[] consisting of N integers and an integer K, the task is to find a subarray of size K with maximum sum and count of distinct elements same as that of the original array.
Examples:
Input: arr[] = {7, 7, 2, 4, 2, 7, 4, 6, 6, 6}, K = 6
Output: 31
Explanation: The given array consists of 4 distinct elements, i.e. {2, 4, 6, 7}. The subarray of size K consisting of all these elements and maximum sum is {2, 7, 4, 6, 6, 6} which starts from 5th index (1-based indexing) of the original array.
Therefore, the sum of the subarray = 2 + 7 + 4 + 6 + 6 + 6 = 31.
Input: arr[] = {1, 2, 5, 5, 19, 2, 1}, K = 4
Output: 27
Naive Approach: The simple approach is to generate all possible subarrays of size K and check if it has the same distinct elements as the original array. If yes then find the sum of this subarray. After checking all the subarrays print the maximum sum of all such subarrays.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int distinct( int arr[], int n)
{
map< int , int > mpp;
for ( int i = 0; i < n; i++)
{
mpp[arr[i]] = 1;
}
return mpp.size();
}
int maxSubSum( int arr[], int n, int k, int totalDistinct)
{
if (k > n)
return 0;
int maxm = 0, sum = 0;
for ( int i = 0; i < n - k + 1; i++)
{
sum = 0;
set< int > st;
for ( int j = i; j < i + k; j++)
{
sum += arr[j];
st.insert(arr[j]);
}
if (( int ) st.size() == totalDistinct)
maxm = max(sum, maxm);
}
return maxm;
}
int main()
{
int arr[] = { 7, 7, 2, 4, 2,
7, 4, 6, 6, 6 };
int K = 6;
int N = sizeof (arr)/ sizeof (arr[0]);
int totalDistinct = distinct(arr, N);
cout << (maxSubSum(arr, N, K, totalDistinct));
return 0;
}
|
Java
import java.util.*;
class GFG {
static int distinct( int arr[], int n)
{
Set<Integer> set = new HashSet<>();
for ( int i = 0 ; i < n; i++) {
set.add(arr[i]);
}
return set.size();
}
static int maxSubSum( int arr[], int n,
int k,
int totalDistinct)
{
if (k > n)
return 0 ;
int max = 0 , sum = 0 ;
for ( int i = 0 ; i < n - k + 1 ; i++) {
sum = 0 ;
Set<Integer> set = new HashSet<>();
for ( int j = i; j < i + k; j++) {
sum += arr[j];
set.add(arr[j]);
}
if (set.size() == totalDistinct)
max = Math.max(sum, max);
}
return max;
}
public static void main(String args[])
{
int arr[] = { 7 , 7 , 2 , 4 , 2 ,
7 , 4 , 6 , 6 , 6 };
int K = 6 ;
int N = arr.length;
int totalDistinct = distinct(arr, N);
System.out.println(
maxSubSum(arr, N, K, totalDistinct));
}
}
|
Python3
def distinct(arr, n):
mpp = {}
for i in range (n):
mpp[arr[i]] = 1
return len (mpp)
def maxSubSum(arr, n, k, totalDistinct):
if (k > n):
return 0
maxm = 0
sum = 0
for i in range (n - k + 1 ):
sum = 0
st = set ()
for j in range (i, i + k, 1 ):
sum + = arr[j]
st.add(arr[j])
if ( len (st) = = totalDistinct):
maxm = max ( sum , maxm)
return maxm
if __name__ = = '__main__' :
arr = [ 7 , 7 , 2 , 4 , 2 , 7 , 4 , 6 , 6 , 6 ]
K = 6
N = len (arr)
totalDistinct = distinct(arr, N)
print (maxSubSum(arr, N, K, totalDistinct))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int distinct( int [] arr, int n)
{
HashSet< int > set = new HashSet< int >();
for ( int i = 0; i < n; i++) {
set .Add(arr[i]);
}
return set .Count;
}
static int maxSubSum( int [] arr, int n,
int k,
int totalDistinct)
{
if (k > n)
return 0;
int max = 0, sum = 0;
for ( int i = 0; i < n - k + 1; i++) {
sum = 0;
HashSet< int > set = new HashSet< int >();
for ( int j = i; j < i + k; j++) {
sum += arr[j];
set .Add(arr[j]);
}
if ( set .Count == totalDistinct)
max = Math.Max(sum, max);
}
return max;
}
public static void Main(String[] args)
{
int [] arr = { 7, 7, 2, 4, 2,
7, 4, 6, 6, 6 };
int K = 6;
int N = arr.Length;
int totalDistinct = distinct(arr, N);
Console.WriteLine(
maxSubSum(arr, N, K, totalDistinct));
}
}
|
Javascript
<script>
function distinct(arr, n)
{
var mpp = new Map();
for ( var i = 0; i < n; i++)
{
mpp.set(arr[i], 1);
}
return mpp.size;
}
function maxSubSum(arr, n,k, totalDistinct)
{
if (k > n)
return 0;
var maxm = 0, sum = 0;
for ( var i = 0; i < n - k + 1; i++)
{
sum = 0;
var st = new Set();
for ( var j = i; j < i + k; j++)
{
sum += arr[j];
st.add(arr[j]);
}
if ( st.size == totalDistinct)
maxm = Math.max(sum, maxm);
}
return maxm;
}
var arr = [7, 7, 2, 4, 2,
7, 4, 6, 6, 6];
var K = 6;
var N = arr.length;
var totalDistinct = distinct(arr, N);
document.write(maxSubSum(arr, N, K, totalDistinct));
</script>
|
Time Complexity: O(N2*log(N))
Auxiliary Space: O(N)
Efficient Approach: To optimize the above approach, the idea is to make use of Map. Follow the steps below to solve the problem:
- Traverse the array once and keep updating the frequency of array elements in the Map.
- Check if the size of the map is equal to the total number of distinct elements present in the original array or not. If found to be true, update the maximum sum.
- While traversing the original array, if the ith traversal crosses K elements in the array, update the Map by deleting an occurrence of (i – K)th element.
- After completing the above steps, print the maximum sum obtained.
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
int distinct(vector< int >arr, int N)
{
set< int > st;
for ( int i = 0; i < N; i++)
{
st.insert(arr[i]);
}
return st.size();
}
int maxSubarraySumUtil(vector< int >arr, int N,
int K, int totalDistinct)
{
if (K > N)
return 0;
int mx = 0;
int sum = 0;
map< int , int > mp;
for ( int i = 0; i < N; i++)
{
mp[arr[i]] += 1;
sum += arr[i];
if (i >= K)
{
mp[arr[i - K]] -= 1;
sum -= arr[i - K];
if (mp[arr[i - K]] == 0)
mp.erase(arr[i - K]);
}
if (mp.size() == totalDistinct)
mx = max(mx, sum);
}
return mx;
}
void maxSubarraySum(vector< int >arr,
int K)
{
int N = arr.size();
int totalDistinct = distinct(arr, N);
cout<<maxSubarraySumUtil(arr, N, K, totalDistinct);
}
int main()
{
vector< int >arr { 7, 7, 2, 4, 2,
7, 4, 6, 6, 6 };
int K = 6;
maxSubarraySum(arr, K);
}
|
Java
import java.util.*;
class GFG {
static int distinct( int arr[], int N)
{
Set<Integer> set = new HashSet<>();
for ( int i = 0 ; i < N; i++) {
set.add(arr[i]);
}
return set.size();
}
static int maxSubarraySumUtil(
int arr[], int N, int K,
int totalDistinct)
{
if (K > N)
return 0 ;
int max = 0 ;
int sum = 0 ;
Map<Integer, Integer> map
= new HashMap<>();
for ( int i = 0 ; i < N; i++) {
map.put(arr[i],
map.getOrDefault(arr[i], 0 ) + 1 );
sum += arr[i];
if (i >= K) {
map.put(arr[i - K],
map.get(arr[i - K]) - 1 );
sum -= arr[i - K];
if (map.get(arr[i - K]) == 0 )
map.remove(arr[i - K]);
}
if (map.size() == totalDistinct)
max = Math.max(max, sum);
}
return max;
}
static void maxSubarraySum( int arr[],
int K)
{
int N = arr.length;
int totalDistinct = distinct(arr, N);
System.out.println(
maxSubarraySumUtil(arr, N, K,
totalDistinct));
}
public static void main(String args[])
{
int arr[] = { 7 , 7 , 2 , 4 , 2 ,
7 , 4 , 6 , 6 , 6 };
int K = 6 ;
maxSubarraySum(arr, K);
}
}
|
Python3
def distinct(arr, N):
st = set ()
for i in range (N):
st.add(arr[i])
return len (st)
def maxSubarraySumUtil(arr, N, K, totalDistinct):
if (K > N):
return 0
mx = 0
sum = 0
mp = {}
for i in range (N):
if (arr[i] in mp):
mp[arr[i]] + = 1
else :
mp[arr[i]] = 1
sum + = arr[i]
if (i > = K):
if (arr[i - K] in mp):
mp[arr[i - K]] - = 1
sum - = arr[i - K]
if (arr[i - K] in mp and mp[arr[i - K]] = = 0 ):
mp.remove(arr[i - K])
if ( len (mp) = = totalDistinct):
mx = max (mx, sum )
return mx
def maxSubarraySum(arr, K):
N = len (arr)
totalDistinct = distinct(arr, N)
print (maxSubarraySumUtil(arr, N, K, totalDistinct))
if __name__ = = '__main__' :
arr = [ 7 , 7 , 2 , 4 , 2 , 7 , 4 , 6 , 6 , 6 ]
K = 6
maxSubarraySum(arr, K)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int distinct(List< int >arr, int N)
{
HashSet< int > st = new HashSet< int >();
for ( int i = 0; i < N; i++)
{
st.Add(arr[i]);
}
return st.Count;
}
static int maxSubarraySumUtil(List< int >arr, int N,
int K, int totalDistinct)
{
if (K > N)
return 0;
int mx = 0;
int sum = 0;
Dictionary< int , int > mp = new Dictionary< int , int >();
for ( int i = 0; i < N; i++)
{
if (mp.ContainsKey(arr[i]))
mp[arr[i]] += 1;
else
mp[arr[i]] = 1;
sum += arr[i];
if (i >= K)
{
if (mp.ContainsKey(arr[i - K]))
mp[arr[i - K]] -= 1;
else
mp[arr[i - K]] = 1;
sum -= arr[i - K];
if (mp[arr[i - K]] == 0)
mp.Remove(arr[i - K]);
}
if (mp.Count == totalDistinct)
mx = Math.Max(mx, sum);
}
return mx;
}
static void maxSubarraySum(List< int >arr,
int K)
{
int N = arr.Count;
int totalDistinct = distinct(arr, N);
Console.WriteLine(maxSubarraySumUtil(arr, N, K, totalDistinct));
}
public static void Main()
{
List< int >arr = new List< int >{ 7, 7, 2, 4, 2,
7, 4, 6, 6, 6 };
int K = 6;
maxSubarraySum(arr, K);
}
}
|
Javascript
<script>
function distinct(arr, N)
{
var st = new Set();
for ( var i = 0; i < N; i++)
{
st.add(arr[i]);
}
return st.size;
}
function maxSubarraySumUtil(arr, N, K, totalDistinct)
{
if (K > N)
return 0;
var mx = 0;
var sum = 0;
var mp = new Map();
for ( var i=0; i<N; i++)
{
if (mp.has(arr[i]))
mp.set(arr[i], mp.get(arr[i])+1)
else
mp.set(arr[i], 1)
sum += arr[i];
if (i >= K)
{
if (mp.has(arr[i-K]))
mp.set(arr[i-K], mp.get(arr[i-K])-1)
sum -= arr[i - K];
if (mp.has(arr[i - K]) && mp.get(arr[i - K])== 0)
mp. delete (arr[i - K]);
}
if (mp.size == totalDistinct)
mx = Math.max(mx, sum);
}
return mx;
}
function maxSubarraySum(arr, K)
{
var N = arr.length;
var totalDistinct = distinct(arr, N);
document.write( maxSubarraySumUtil(arr, N, K, totalDistinct));
}
var arr = [7, 7, 2, 4, 2,
7, 4, 6, 6, 6 ];
var K = 6;
maxSubarraySum(arr, K);
</script>
|
Time Complexity: O(N*log (N))
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...