在 K 大小的子阵列中最大化每个元素的总和提升到其频率的幂
给定一个包含N个元素的数组arr[]和一个整数K 。任务是找到大小为K的子数组中元素的最大总和,每个元素都提高到子数组中其频率的幂。
例子:
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.
朴素方法:最简单的方法是生成所有子数组。然后为每个子数组计算元素的频率并生成总和。现在检查总和以找到最大值。
时间复杂度: O(N*K)
辅助空间: O(N*K)
高效方法:一种有效的方法是使用滑动窗口概念来避免生成所有子数组。然后为每个窗口计算其中元素的频率并找出总和。所有窗口中的最大总和就是答案。
时间复杂度: O(N*K)
辅助空间: O(K)
最有效的方法:这个想法也是基于滑动窗口技术。但是在这种方法中,避免了每个窗口的每个元素的计数频率。请按照以下步骤实施该想法:
- 维护一个大小为K的窗口,它表示子数组。
- 当窗口向右移动一个位置时,减去紧靠窗口左边的元素和窗口最右边的元素的贡献。
- 现在通过减小窗口左侧元素的频率并增加窗口最右侧元素的频率来调整频率。
- 根据窗口左边的元素和窗口最右边的元素的新频率加回贡献。
下面是上述方法的实现。
C++
// C++ code to implement above approach
#include
using namespace std;
#define mod 1000000007
// Function to find the maximum sum
// of a K sized subarray
long long int maxSum(vector& arr,
int N, int K)
{
long long int ans = 0;
// Map to store frequency of elements
// of the K sized subarray
unordered_map 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 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 arr, int N, int K) {
long ans = 0;
// Map to store frequency of elements
// of the K sized subarray
HashMap freq = new HashMap();
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 arr = new ArrayList();
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 arr, int N, int K)
{
long ans = 0;
// Map to store frequency of elements
// of the K sized subarray
Dictionary freq
= new Dictionary();
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 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 arr = new List() { 2, 1, 2, 3, 3 };
// Output the variable to STDOUT
Console.WriteLine(maxSum(arr, N, K));
}
}
// This code is contributed by ukasp.
Javascript
11
时间复杂度: O(N)
辅助空间: O(K)