📜  在 K 大小的子阵列中最大化每个元素的总和提升到其频率的幂

📅  最后修改于: 2022-05-13 01:56:06.334000             🧑  作者: Mango

在 K 大小的子阵列中最大化每个元素的总和提升到其频率的幂

给定一个包含N个元素的数组arr[]和一个整数K 。任务是找到大小为K的子数组中元素的最大总和,每个元素都提高到子数组中其频率的幂。

例子:

朴素方法:最简单的方法是生成所有子数组。然后为每个子数组计算元素的频率并生成总和。现在检查总和以找到最大值。

时间复杂度: 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)