Open In App

Maximum sum of subarrays having distinct elements of length K

Last Updated : 28 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find maximum sum
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;
 
    // Iterating for length k
    while (i < k && i < n) {
 
        currentSum += arr[i];
        mp[arr[i]]++;
 
        i++;
    }
 
    // If distinct elements present in map
    // equal to k
    if (mp.size() == k) {
        maxSum = currentSum;
    }
 
    // Iterating over the left array
    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;
    }
 
    // Returning the maximum sum
    return maxSum;
}
 
// Driver Code
int main()
{
    vector<int> arr = { 1, 5, 4, 2, 9, 9, 9 };
    int k = 3;
 
    // Function call
    cout << helper(arr, k);
    return 0;
}


Java




// Java implementation of the above approach
 
import java.io.*;
import java.util.*;
 
class GFG {
  // Function to find maximum sum
  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;
 
    //Iterating for length k
    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 distinct elements present in map
    // equal to k
    if(mp.size() == k) {
      maxSum = currentSum;
    }
 
    //Iterating over the left array
    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++;
      }
 
    }
 
    // Returning the maximum sum
    return maxSum;
  }
 
  // Driver Code
  public static void main(String[] args) {
    int[] arr = { 1, 5, 4, 2, 9, 9, 9 };
    int k = 3;
 
    // Function call
    System.out.println(helper(arr, k));
  }
}


Python3




# Python implementation of the above approach
from collections import defaultdict
 
# Function to find maximum sum
def helper(arr, k):
    mp = defaultdict(int)
    currentSum = 0
    maxSum = 0
    n = len(arr)
    left = 0
    i = 0
 
    # Iterating for length k
    while i < k and i < n:
        currentSum += arr[i]
        mp[arr[i]] += 1
 
        i += 1
 
    # If distinct elements present in map
    # equal to k
    if len(mp) == k:
        maxSum = currentSum
 
    # Iterating over the left array
    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
 
    # Returning the maximum sum
    return maxSum
 
# Driver Code
if __name__ == "__main__":
    arr = [1, 5, 4, 2, 9, 9, 9]
    k = 3
 
    # Function call
    print(helper(arr, k))
 
# This code is contributed by ik_9


C#




// C# code to implement the approach
using System;
using System.Collections.Generic;
 
class Gfg
{
   
  // Function to find maximum sum
  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;
 
    // Iterating for length k
    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 distinct elements present in map
    // equal to k
    if (mp.Count == k) {
      maxSum = currentSum;
    }
 
    // Iterating over the left array
    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++;
    }
 
    // Returning the maximum sum
    return maxSum;
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    List<int> arr = new List<int>{ 1, 5, 4, 2, 9, 9, 9 };
    int k = 3;
 
    // Function call
    Console.Write(helper(arr, k));
  }
}
 
// This code is contributed by imruhrbf8.


Javascript




<script>
       //JavaScript code for the above approach
       // Function to find maximum sum
       function findMaxSum(arr, k) {
           // Create an unordered map to store element counts
           const elementCounts = new Map();
 
           let currentSum = 0;
           let maxSum = 0;
           const n = arr.length;
           let left = 0;
           let i = 0;
 
           // Iterate for the first k elements
           while (i < k && i < n) {
               // Add element value to the current sum and update element count
               currentSum += arr[i];
               elementCounts.set(arr[i], (elementCounts.get(arr[i]) || 0) + 1);
               i++;
           }
 
           // If the number of distinct elements in the map is equal to k
           if (elementCounts.size === k) {
               maxSum = currentSum;
           }
 
           // Iterate over the left array
           for (let i = k; i < n; i++) {
               // Increment element count and decrement element count for left element
               elementCounts.set(arr[i], (elementCounts.get(arr[i]) || 0) + 1);
               elementCounts.set(arr[left], elementCounts.get(arr[left]) - 1);
 
               // If element count for left element becomes 0, remove it from the map
               if (elementCounts.get(arr[left]) === 0) {
                   elementCounts.delete(arr[left]);
               }
 
               // Add element at right index to the current sum and subtract element at left index
               currentSum += arr[i];
               currentSum -= arr[left];
 
               // If the number of distinct elements in the map is equal to k, update the maximum sum
               if (elementCounts.size === k) {
                   maxSum = Math.max(maxSum, currentSum);
               }
 
               // Move the left index to the right by 1
               left++;
           }
 
           // Return the maximum sum
           return maxSum;
       }
 
       // Driver code
       const arr = [1, 5, 4, 2, 9, 9, 9];
       const k = 3;
 
       document.write(findMaxSum(arr, k));
 
// This code is contributed by Potta Lokesh
 
   </script>


Output

15

Time Complexity: O(n) 
Auxiliary Space: O(k)

Another Approach: Sliding window technique

  1. 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. 
     
  2. 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.                             
     
  3. 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.
     
  4. If all elements in the subarray are distinct, update the answer ans:                                                                                                                                                         a)Set ans to the maximum of ans and sum.
     
  5. Remove the ith element from freq and sum:                                                                                                                                                                                             a)Decrement freq[nums[i]].
    b)Subtract nums[i] from sum.
     
  6. Move the pointers i and j ahead:                                                                                                                                                                                                             a)Increment i and j by 1.
     
  7. If the subarray is not of length k, increase the length:                                                                                                                                                                               a)Increment j by 1.
     
  8. Continue iterating until the end of the array is reached.
     
  9. 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]]++; // adding jth element
        sum += nums[j]; // adding jth element to sum
        if(j - i + 1 == k){ // if the subarray is of length k
            bool distinct = true;
            for(int x = 0; x <= 100000; x++){ // check if all elements are distinct
                if(freq[x] > 1){
                    distinct = false;
                    break;
                }
            }
            if(distinct){ // if all elements are distinct, update answer
                ans = max(ans, sum);
            }
            freq[nums[i]]--; // remove the ith element
            sum -= nums[i]; // subtract the ith element from sum
            i++; j++; // move the pointers ahead
        }
        else{
            j++; // if the subarray is not of length k, increase the length
        }
    }
    return ans; // return the answer
}
 
int main(){
    vector<int> nums = {1, 5, 4, 2, 9, 9, 9};
    int k = 3;
    cout<<maxSum(nums,k)<<endl; // 15
   // nums = {4, 4, 4};
   // k = 3;
   // cout<<maxSum(nums,k)<<endl; // 0
    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)]++; // adding jth element
            sum += nums.get(j); // adding jth element to sum
            if(j - i + 1 == k) { // if the subarray is of length k
                boolean distinct = true;
                for(int x = 0; x <= 100000; x++) { // check if all elements are distinct
                    if(freq[x] > 1) {
                        distinct = false;
                        break;
                    }
                }
                if(distinct) { // if all elements are distinct, update answer
                    ans = Math.max(ans, sum);
                }
                freq[nums.get(i)]--; // remove the ith element
                sum -= nums.get(i); // subtract the ith element from sum
                i++; j++; // move the pointers ahead
            }
            else {
                j++; // if the subarray is not of length k, increase the length
            }
        }
        return ans; // return the answer
    }
     
    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)); // 15
       // nums = new ArrayList<>(Arrays.asList(4, 4, 4));
       // k = 3;
       // System.out.println(maxSum(nums, k)); // 0
    }
}


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]]++; // adding jth element
            sum += nums[j]; // adding jth element to sum
            if (j - i + 1 == k)
            { // if the subarray is of length k
                bool distinct = true;
                for (int x = 0; x <= 100000; x++)
                { // check if all elements are distinct
                    if (freq[x] > 1)
                    {
                        distinct = false;
                        break;
                    }
                }
                if (distinct)
                { // if all elements are distinct, update answer
                    ans = Math.Max(ans, sum);
                }
                freq[nums[i]]--; // remove the ith element
                sum -= nums[i]; // subtract the ith element from sum
                i++; j++; // move the pointers ahead
            }
            else
            {
                j++; // if the subarray is not of length k, increase the length
            }
        }
        return ans; // return the answer
    }
 
    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)); // 15
        //nums = new List<int>(new int[] { 4, 4, 4 });
       // k = 3;
        //Console.WriteLine(maxSum(nums, k)); // 0
    }
}


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)) # 15
#nums = [4, 4, 4]
#k = 3
#print(max_sum(nums, k)) # 0


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]]++; // adding jth element
    sum += nums[j]; // adding jth element to sum
    if (j - i + 1 == k) { // if the subarray is of length k
      let distinct = true;
      for (let x = 0; x <= 100000; x++) { // check if all elements are distinct
        if (freq[x] > 1) {
          distinct = false;
          break;
        }
      }
      if (distinct) { // if all elements are distinct, update answer
        ans = Math.max(ans, sum);
      }
      freq[nums[i]]--; // remove the ith element
      sum -= nums[i]; // subtract the ith element from sum
      i++; j++; // move the pointers ahead
    } else {
      j++; // if the subarray is not of length k, increase the length
    }
  }
  return ans; // return the answer
}
 
const nums = [1, 5, 4, 2, 9, 9, 9];
const k = 3;
console.log(maxSum(nums, k)); // 15
//const nums2 = [4, 4, 4];
//const k2 = 3;
//console.log(maxSum(nums2, k2)); // 0


Output

15

Time Complexity: O(n*k)

Auxiliary Space: O(1)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads