Maximize sum of each element raised to power of its frequency in K sized subarray
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> |
11
Time Complexity: O(N)
Auxiliary Space: O(K)