Open In App

Maximize sum of each element raised to power of its frequency in K sized subarray

Last Updated : 09 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of N elements and an integer K. The task is to find the maximum sum of elements in a subarray of size K, with each element raised to the power of its frequency in the subarray.

Examples:

Input: arr[] = { 2, 1, 2, 3, 3 }, N = 5, K = 3
Output: 11
Explanation: Required subarray of size 3 = {2, 3, 3}. The sum is 21 + 32 = 11, which is the maximum sum possible.

Input: arr[] = { 4, 9, 6, 5}, N = 4, K = 3
Output: 20
Explanation: The two subarrays of size 3 are {4, 9, 6} and {9, 6, 5}. The subarray {9, 6, 5} has the sum = 20.

 

Naive Approach: The simplest approach is to generate all the subarrays. Then for each subarray count the frequency of elements and generate the sum. Now check the sums to find the maximum one.

Time complexity: O(N*K)
Auxiliary Space: O(N*K)

Efficient Approach: An efficient approach is to use sliding window concept to avoid generating all the subarrays. Then for each window count the frequency of the elements in it and find out the sum. The maximum sum among all the windows is the answer.

Time Complexity: O(N*K)
Auxiliary Space: O(K)

Most Efficient Approach: This idea is also based on sliding window technique. But in this approach counting frequency of each element for each window is avoided. Follow the steps below to implement the idea:

  • Maintain a window of size K which denotes the subarray.
  • When the window shifts one position to right subtract the contribution of the element immediately left to the window and rightmost element of the window.
  • Now adjust the frequency by decrementing the frequency of the element immediately left to the window and incrementing the frequency of the rightmost element of the window.
  • Add back the contributions according to the new frequencies of the elements immediately left to the window and the rightmost element of the window.

Below is the implementation of the above approach.

C++




// C++ code to implement above approach
#include <bits/stdc++.h>
 
using namespace std;
#define mod 1000000007
 
// Function to find the maximum sum
// of a K sized subarray
long long int maxSum(vector<int>& arr,
                     int N, int K)
{
    long long int ans = 0;
 
    // Map to store frequency of elements
    // of the K sized subarray
    unordered_map<int, int> freq;
    for (int j = 0; j < K; j++) {
        freq[arr[j]]++;
    }
 
    long long int sum = 0;
 
    // Sum of the first K sized subarray
    for (auto m : freq)
        sum = (sum
               + ((long long int)
                  (pow(m.first, m.second)))
                     % mod)% mod;
     
    // Variable to store ans
    ans = max(ans, sum);
 
    for (int i = 1; i <= N - K; i++) {
        // Subtract the contribution of
        // the element immediately left
        // to the subarray
        sum -= freq[arr[i - 1]] > 0
                   ?
          ((long long int)
           (pow(arr[i - 1],
               freq[arr[i - 1]])))% mod
          : 0;
         
        // Update the frequency of
        // the element immediately left
        // to the subarray
        freq[arr[i - 1]]--;
         
        // Add back the contribution of
        // the element immediately left
        // to the subarray
        sum += freq[arr[i - 1]] > 0
                   ?
          ((long long int)
           (pow(arr[i - 1],
                freq[arr[i - 1]])))% mod
                   : 0;
 
        // Subtract the contribution of
        // the rightmost element
        // of the subarray
        sum -= freq[arr[i + K - 1]] > 0
                   ?
          ((long long int)
           (pow(arr[i + K - 1],
                freq[arr[i + K - 1]])))% mod
                   : 0;
 
        // Update the frequency of the
        // rightmost element of the subarray
        freq[arr[i + K - 1]]++;
         
        // Add back the contribution of the
        // rightmost element of the subarray
        sum += freq[arr[i + K - 1]] > 0
                   ?
          ((long long int)
           (pow(arr[i + K - 1],
                freq[arr[i + K - 1]])))% mod
                   : 0;
 
        // Update the answer
        ans = max(ans, sum);
    }
 
    return ans;
}
 
// Driver code
int main()
{
    // Declare the variable
    int N = 5, K = 3;
 
    vector<int> arr = { 2, 1, 2, 3, 3 };
 
    // Output the variable to STDOUT
    cout << maxSum(arr, N, K);
 
    return 0;
}


Java




// Java code to implement above approach
import java.util.ArrayList;
import java.util.HashMap;
 
class GFG {
    static int mod = 1000000007;
 
    // Function to find the maximum sum
    // of a K sized subarray
    static long maxSum(ArrayList<Integer> arr, int N, int K) {
        long ans = 0;
 
        // Map to store frequency of elements
        // of the K sized subarray
        HashMap<Integer, Integer> freq = new HashMap<Integer, Integer>();
        for (int j = 0; j < K; j++) {
            if (freq.containsKey(arr.get(j))) {
                freq.put(arr.get(j), freq.get(arr.get(j)) + 1);
            } else
                freq.put(arr.get(j), 1);
        }
 
        long sum = 0;
 
        // Sum of the first K sized subarray
        for (int m : freq.keySet()) {
            sum = (sum + ((long) (Math.pow(m, freq.get(m)))) % mod) % mod;
        }
 
        // Variable to store ans
        ans = Math.max(ans, sum);
 
        for (int i = 1; i <= N - K; i++) {
            // Subtract the contribution of
            // the element immediately left
            // to the subarray
            if (freq.containsKey(arr.get(i - 1))) {
                sum -= freq.get(arr.get(i - 1)) > 0
                        ? ((long) (Math.pow(
                                arr.get(i - 1),
                                freq.get(arr.get(i - 1)))))
                                % mod
                        : 0;
 
                // Update the frequency of
                // the element immediately left
                // to the subarray
                freq.put(arr.get(i - 1), freq.get(arr.get(i - 1)) - 1);
 
                // Add back the contribution of
                // the element immediately left
                // to the subarray
                sum += freq.get(arr.get(i - 1)) > 0
                        ? ((long) (Math.pow(
                                arr.get(i - 1),
                                freq.get(arr.get(i - 1)))))
                                % mod
                        : 0;
            }
            // Subtract the contribution of
            // the rightmost element
            // of the subarray
            if (freq.containsKey(arr.get(i + K - 1))) {
                sum -= freq.get(arr.get(i + K - 1)) > 0
                        ? ((long) (Math.pow(
                                arr.get(i + K - 1),
                                freq.get(arr.get(i + K - 1)))))
                                % mod
                        : 0;
            }
 
            // Update the frequency of the
            // rightmost element of the subarray
            if (freq.containsKey(arr.get(i + K - 1)))
                freq.put(arr.get(i + K - 1), freq.get(arr.get(i + K - 1)) + 1);
            else
                freq.put(arr.get(i + K - 1), 1);
 
            // Add back the contribution of the
            // rightmost element of the subarray
 
            sum += freq.get(arr.get(i + K - 1)) > 0
                    ? ((long) (Math.pow(
                            arr.get(i + K - 1),
                            freq.get(arr.get(i + K - 1)))))
                            % mod
                    : 0;
 
            // Update the answer
            ans = Math.max(ans, sum);
        }
        return ans;
    }
 
    // Driver code
    public static void main(String args[])
    {
       
        // Declare the variable
        int N = 5, K = 3;
 
        ArrayList<Integer> arr = new ArrayList<Integer>();
        arr.add(2);
        arr.add(1);
        arr.add(2);
        arr.add(3);
        arr.add(3);
 
        // Output the variable to STDOUT
        System.out.println(maxSum(arr, N, K));
    }
}
 
// This code is contributed by Saurabh Jaiswal


Python3




# Python code for the above approach
mod = 1000000007
 
# Function to find the maximum sum
# of a K sized subarray
def maxSum(arr, N, K):
    ans = 0
 
    # Map to store frequency of elements
    # of the K sized subarray
    freq = [0] * 100001
    for j in range(K):
        freq[arr[j]] += 1
 
    sum = 0
 
    # Sum of the first K sized subarray
    for i in range(len(freq)):
        if (freq[i] != 0):
            sum += ((i ** freq[i]) % mod) % mod
 
    # Variable to store ans
    ans = max(ans, sum)
 
    for i in range(1, N - K + 1):
        # Subtract the contribution of
        # the element immediately left
        # to the subarray
        sum -= ((arr[i - 1] ** freq[arr[i - 1]])
                ) % mod if freq[arr[i - 1]] > 0 else 0
 
        # Update the frequency of
        # the element immediately left
        # to the subarray
        freq[arr[i - 1]] -= 1
 
        # Add back the contribution of
        # the element immediately left
        # to the subarray
        sum += ((arr[i - 1] ** freq[arr[i - 1]])
                ) % mod if freq[arr[i - 1]] > 0 else 0
 
        # Subtract the contribution of
        # the rightmost element
        # of the subarray
        sum -= ((arr[i + K - 1] ** freq[arr[i + K - 1]])
                ) % mod if freq[arr[i + K - 1]] > 0 else 0
 
        # Update the frequency of the
        # rightmost element of the subarray
        freq[arr[i + K - 1]] += 1
 
        # Add back the contribution of the
        # rightmost element of the subarray
        sum += ((arr[i + K - 1] ** freq[arr[i + K - 1]])
                ) % mod if freq[arr[i + K - 1]] > 0 else 0
 
        # Update the answer
        print("ans = ",ans, "sum = ",sum)
        ans = max(ans, sum)
 
    return ans
 
# Driver code
 
# Declare the variable
N = 5
K = 3
 
arr = [2, 1, 2, 3, 3]
 
print(maxSum(arr, N, K))
 
# This code is contributed by gfgking


C#




// C# code to implement above approach
using System;
using System.Collections.Generic;
class GFG {
  static int mod = 1000000007;
 
  // Function to find the maximum sum
  // of a K sized subarray
  static long maxSum(List<int> arr, int N, int K)
  {
    long ans = 0;
 
    // Map to store frequency of elements
    // of the K sized subarray
    Dictionary<int, int> freq
      = new Dictionary<int, int>();
    for (int j = 0; j < K; j++) {
      if (freq.ContainsKey(arr[j]))
        freq[arr[j]]++;
      else
        freq[arr[j]] = 1;
    }
 
    long sum = 0;
 
    // Sum of the first K sized subarray
    foreach(KeyValuePair<int, int> m in freq)
    {
      sum = (sum
             + ((long)(Math.Pow(m.Key, m.Value)))
             % mod)
        % mod;
    }
 
    // Variable to store ans
    ans = Math.Max(ans, sum);
 
    for (int i = 1; i <= N - K; i++) {
      // Subtract the contribution of
      // the element immediately left
      // to the subarray
      if (freq.ContainsKey(arr[i - 1])) {
        sum -= freq[arr[i - 1]] > 0
          ? ((long)(Math.Pow(
            arr[i - 1],
            freq[arr[i - 1]])))
          % mod
          : 0;
 
        // Update the frequency of
        // the element immediately left
        // to the subarray
        freq[arr[i - 1]]--;
 
        // Add back the contribution of
        // the element immediately left
        // to the subarray
        sum += freq[arr[i - 1]] > 0
          ? ((long)(Math.Pow(
            arr[i - 1],
            freq[arr[i - 1]])))
          % mod
          : 0;
      }
      // Subtract the contribution of
      // the rightmost element
      // of the subarray
      if (freq.ContainsKey(arr[i + K - 1])) {
        sum -= freq[arr[i + K - 1]] > 0
          ? ((long)(Math.Pow(
            arr[i + K - 1],
            freq[arr[i + K - 1]])))
          % mod
          : 0;
      }
 
      // Update the frequency of the
      // rightmost element of the subarray
      if (freq.ContainsKey(arr[i + K - 1]))
        freq[arr[i + K - 1]]++;
      else
        freq[arr[i + K - 1]] = 1;
 
      // Add back the contribution of the
      // rightmost element of the subarray
 
      sum += freq[arr[i + K - 1]] > 0
        ? ((long)(Math.Pow(
          arr[i + K - 1],
          freq[arr[i + K - 1]])))
        % mod
        : 0;
 
      // Update the answer
      ans = Math.Max(ans, sum);
    }
    return ans;
  }
 
  // Driver code
  public static void Main()
  {
    // Declare the variable
    int N = 5, K = 3;
 
    List<int> arr = new List<int>() { 2, 1, 2, 3, 3 };
 
    // Output the variable to STDOUT
    Console.WriteLine(maxSum(arr, N, K));
  }
}
 
// This code is contributed by ukasp.


Javascript




<script>
       // JavaScript code for the above approach
 
       let mod = 1000000007
 
       // Function to find the maximum sum
       // of a K sized subarray
       function maxSum(arr,
           N, K) {
           let ans = 0;
 
           // Map to store frequency of elements
           // of the K sized subarray
           let freq = new Array(100001).fill(0);
           for (let j = 0; j < K; j++) {
               freq[arr[j]]++;
           }
 
           let sum = 0;
 
           // Sum of the first K sized subarray
           for (let i = 0; i < freq.length; i++)
               if (freq[i] != 0) {
                   sum = (sum
                       + (
                           (Math.pow(i, freq[i])))
                       % mod) % mod;
               }
           // Variable to store ans
           ans = Math.max(ans, sum);
 
           for (let i = 1; i <= N - K; i++) {
               // Subtract the contribution of
               // the element immediately left
               // to the subarray
               sum -= freq[arr[i - 1]] > 0
                   ?
                   (
                       (Math.pow(arr[i - 1],
                           freq[arr[i - 1]]))) % mod
                   : 0;
 
               // Update the frequency of
               // the element immediately left
               // to the subarray
               freq[arr[i - 1]]--;
 
               // Add back the contribution of
               // the element immediately left
               // to the subarray
               sum += freq[arr[i - 1]] > 0
                   ?
                   (
                       (Math.pow(arr[i - 1],
                           freq[arr[i - 1]]))) % mod
                   : 0;
 
               // Subtract the contribution of
               // the rightmost element
               // of the subarray
               sum -= freq[arr[i + K - 1]] > 0
                   ?
                   (
                       (Math.pow(arr[i + K - 1],
                           freq[arr[i + K - 1]]))) % mod
                   : 0;
 
               // Update the frequency of the
               // rightmost element of the subarray
               freq[arr[i + K - 1]]++;
 
               // Add back the contribution of the
               // rightmost element of the subarray
               sum += freq[arr[i + K - 1]] > 0
                   ?
                   (
                       (Math.pow(arr[i + K - 1],
                           freq[arr[i + K - 1]]))) % mod
                   : 0;
 
               // Update the answer
               ans = Math.max(ans, sum);
           }
 
           return ans;
       }
 
       // Driver code
 
       // Declare the variable
       let N = 5, K = 3;
 
       let arr = [2, 1, 2, 3, 3];
 
        
       document.write(maxSum(arr, N, K));
 // This code is contributed by Potta Lokesh
   </script>


Output

11

Time Complexity: O(N)
Auxiliary Space: O(K)

Approach: Frequency-Based Maximum Sum Subarray

Here are the steps for the “Frequency-Based Maximum Sum Subarray” approach:

  1. Create an empty dictionary to store the frequency of each element in the given array.
  2. Iterate over the given array, and for each element, increment its frequency in the dictionary.
  3. Initialize a variable max_sum to negative infinity.
  4. Iterate over all possible subarrays of length k. For each subarray, calculate the sum of each element raised to the power of its frequency in the subarray. To do this, iterate over the subarray, and for each element, use its frequency from the dictionary to calculate its contribution to the subarray sum. Add up the contributions for all elements in the subarray to get the subarray sum.
  5. Update the max_sum variable with the subarray sum if it is greater than the current max_sum.
  6. Return the max_sum variable as the result.
     

C++




#include<math.h>
#include <iostream>
#include <climits>
using namespace std;
 
int max_sum_subarray(int arr[], int n, int k) {
    int freq[101] = {0};
    for (int i = 0; i < n; i++) {
        freq[arr[i]]++;
    }
 
    int max_sum = INT_MIN;
    for (int i = 0; i <= n-k; i++) {
        int subarray_sum = 0;
        for (int j = i; j < i+k; j++) {
            subarray_sum += pow(arr[j], freq[arr[j]]);
        }
        max_sum = max(max_sum, subarray_sum);
    }
 
    return max_sum;
}
 
int main() {
    int arr[] = {4, 9, 6, 5};
    int n = 4;
    int k = 3;
    cout << max_sum_subarray(arr, n, k) << endl;
    return 0;
}


Python3




def max_sum_subarray(arr, n, k):
    freq = {}
    for i in arr:
        freq[i] = freq.get(i, 0) + 1
 
    max_sum = float('-inf')
    for i in range(n-k+1):
        subarray = arr[i:i+k]
        subarray_sum = sum([pow(x, freq[x]) for x in subarray])
        max_sum = max(max_sum, subarray_sum)
 
    return max_sum
# EXAMPLE
arr = [4, 9, 6, 5]
n = 4
k = 3
print(max_sum_subarray(arr, n, k)) # Output: 20


C#




using System;
using System.Collections.Generic;
 
class GFG
{
 
  // Function to find the maximum sum of subarray of size
  // k
  public static int MaxSumSubarray(int[] arr, int n,
                                   int k)
  {
 
    // Initialize a dictionary to store the frequency of
    // each element
    Dictionary<int, int> freq
      = new Dictionary<int, int>();
    foreach(int i in arr)
    {
      if (freq.ContainsKey(i))
        freq[i]++;
      else
        freq[i] = 1;
    }
 
    int maxSum = int.MinValue;
    for (int i = 0; i <= n - k; i++)
    {
 
      // Create a subarray of size k
      int[] subarray = new int[k];
      Array.Copy(arr, i, subarray, 0, k);
 
      int subarraySum = 0;
 
      // Calculate the sum of the frequency
      // powered elements in the subarray
      foreach(int x in subarray)  subarraySum += (int)Math.Pow(x, freq[x]);
 
      // Update maxSum
      maxSum = Math.Max(maxSum, subarraySum);
    }
 
    return maxSum;
  }
 
  public static void Main(string[] args)
  {
    // EXAMPLE
    int[] arr = new int[] { 4, 9, 6, 5 };
    int n = 4;
    int k = 3;
    Console.WriteLine(MaxSumSubarray(arr, n, k));
  }
}


Javascript




function max_sum_subarray(arr, n, k) {
    let freq = Array(101).fill(0);
    for (let i = 0; i < n; i++) {
        freq[arr[i]]++;
    }
 
    let max_sum = Number.MIN_SAFE_INTEGER;
    for (let i = 0; i <= n-k; i++) {
        let subarray_sum = 0;
        for (let j = i; j < i+k; j++) {
            subarray_sum += Math.pow(arr[j], freq[arr[j]]);
        }
        max_sum = Math.max(max_sum, subarray_sum);
    }
 
    return max_sum;
}
 
let arr = [4, 9, 6, 5];
let n = 4;
let k = 3;
console.log(max_sum_subarray(arr, n, k));


Java




// Java program for the above approach
import java.util.Arrays;
 
public class Main {
 
    // Function to find the maximum
    // subarray sum
    public static int maxSumSubarray(int[] arr, int n,
                                     int k)
    {
        int[] freq = new int[101];
        for (int i = 0; i < n; i++) {
            freq[arr[i]]++;
        }
 
        // Stores the maximum sum
        int maxSum = Integer.MIN_VALUE;
        for (int i = 0; i <= n - k; i++) {
            int subarraySum = 0;
            for (int j = i; j < i + k; j++) {
                subarraySum
                    += Math.pow(arr[j], freq[arr[j]]);
            }
 
            // Update the maximum sum
            maxSum = Math.max(maxSum, subarraySum);
        }
 
        // Return the maximum sum of subarray
        return maxSum;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[] arr = { 4, 9, 6, 5 };
        int n = 4;
        int k = 3;
        System.out.println(maxSumSubarray(arr, n, k));
    }
}


Output

20

Time complexity: O(n*k), 
Auxiliary space: O(n)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads