在所有长度为 K 的子数组上最大化子数组的最小值和子数组的总和的乘积
给定一个包含N个整数的数组arr[] ,任务是在具有K个元素的所有可能子数组中找到 ( min * sum ) 的最大可能值,其中min表示子数组的最小整数, sum表示所有元素的总和的子数组。
示例:
Input: arr[] = {1, 2, 3, 2}, K = 3
Output: 14
Explanation: For the subarray {2, 3, 2}, the score is given as min(2, 3, 2) * sum(2, 3, 2) = 2 * 7 = 14, which is the maximum possible.
Input: arr[] = {3, 1, 5, 6, 4, 2}, K = 2
Output: 55
方法:上述问题可以借助滑动窗口技术来解决,方法是在数组遍历期间维护一个包含K个元素的窗口,并在变量minimum和分别求和。可以使用类似于此处讨论的算法的多集数据结构来计算所有K大小的子阵列的最小值,并且可以使用此处讨论的算法计算总和。所有K大小窗口的minimum * sum的最大值是必需的答案。
下面是上述方法的实现:
C++
// C++ implementation for the above approach
#include
using namespace std;
// Function to the maximum value of min * sum
// over all possible subarrays of K elements
int maxMinSum(vector arr, int K)
{
// Store the array size
int N = arr.size();
// Multiset data structure to calculate the
// minimum over all K sized subarrays
multiset s;
// Stores the sum of the surrent window
int sum = 0;
// Loop to calculate the sum and min of the
// 1st window of size K
for (int i = 0; i < K; i++) {
s.insert(arr[i]);
sum += arr[i];
}
// Stores the required answer
int ans = sum * (*s.begin());
// Loop to iterate over the remaining windows
for (int i = K; i < N; i++) {
// Add the current value and remove the
// (i-K)th value from the sum
sum += (arr[i] - arr[i - K]);
// Update the set
s.erase(s.find(arr[i - K]));
s.insert(arr[i]);
// Update answer
ans = max(ans, sum * (*s.begin()));
}
// Return Answer
return ans;
}
// Driver Code
int main()
{
vector arr = { 3, 1, 5, 6, 4, 2 };
int K = 2;
cout << maxMinSum(arr, K);
return 0;
}
Java
// Java implementation for the above approach
import java.util.HashSet;
class GFG {
// Function to the maximum value of min * sum
// over all possible subarrays of K elements
public static int maxMinSum(int[] arr, int K)
{
// Store the array size
int N = arr.length;
// Multiset data structure to calculate the
// minimum over all K sized subarrays
HashSet s = new HashSet();
// Stores the sum of the surrent window
int sum = 0;
// Loop to calculate the sum and min of the
// 1st window of size K
for (int i = 0; i < K; i++) {
s.add(arr[i]);
sum += arr[i];
}
// Stores the required answer
int ans = sum * (s.iterator().next());
// Loop to iterate over the remaining windows
for (int i = K; i < N; i++) {
// Add the current value and remove the
// (i-K)th value from the sum
sum += (arr[i] - arr[i - K]);
// Update the set
if (s.contains(arr[i - K]))
s.remove(arr[i - K]);
s.add(arr[i]);
// Update answer
ans = Math.max(ans, sum * (s.iterator().next()));
}
// Return Answer
return ans;
}
// Driver Code
public static void main(String args[]) {
int[] arr = { 3, 1, 5, 6, 4, 2 };
int K = 2;
System.out.println(maxMinSum(arr, K));
}
}
// This code is contributed by saurabh_jaiswal.
Python3
# python implementation for the above approach
# Function to the maximum value of min * sum
# over all possible subarrays of K elements
def maxMinSum(arr, K):
# Store the array size
N = len(arr)
# Multiset data structure to calculate the
# minimum over all K sized subarrays
s = set()
# Stores the sum of the surrent window
sum = 0
# Loop to calculate the sum and min of the
# 1st window of size K
for i in range(0, K):
s.add(arr[i])
sum += arr[i]
# Stores the required answer
ans = sum * (list(s)[0])
# Loop to iterate over the remaining windows
for i in range(K, N):
# Add the current value and remove the
# (i-K)th value from the sum
sum += (arr[i] - arr[i - K])
# Update the set
if arr[i-K] in s:
s.remove(arr[i-K])
s.add(arr[i])
# Update answer
ans = max(ans, sum * (list(s)[0]))
# Return Answer
return ans
# Driver Code
if __name__ == "__main__":
arr = [3, 1, 5, 6, 4, 2]
K = 2
print(maxMinSum(arr, K))
# This code is contributed by rakeshsahni
C#
// C# implementation for the above approach
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
// Function to the maximum value of min * sum
// over all possible subarrays of K elements
public static int maxMinSum(int[] arr, int K)
{
// Store the array size
int N = arr.Length;
// Multiset data structure to calculate the
// minimum over all K sized subarrays
HashSet s = new HashSet();
// Stores the sum of the surrent window
int sum = 0;
// Loop to calculate the sum and min of the
// 1st window of size K
for (int i = 0; i < K; i++) {
s.Add(arr[i]);
sum += arr[i];
}
// Stores the required answer
int ans = sum * (s.ToList()[0]);
// Loop to iterate over the remaining windows
for (int i = K; i < N; i++) {
// Add the current value and remove the
// (i-K)th value from the sum
sum += (arr[i] - arr[i - K]);
// Update the set
if (s.Contains(arr[i - K]))
s.Remove(arr[i - K]);
s.Add(arr[i]);
// Update answer
ans = Math.Max(ans, sum * (s.ToList()[0]));
}
// Return Answer
return ans;
}
// Driver Code
public static void Main() {
int[] arr = { 3, 1, 5, 6, 4, 2 };
int K = 2;
Console.Write(maxMinSum(arr, K));
}
}
// This code is contributed by saurabh_jaiswal.
Javascript
输出:
55
时间复杂度: O(N*log N)
辅助空间: O(N)