给定一个由N个正整数组成的数组arr [] ,任务是找到子数组和与该子数组的最小元素的最大乘积。
例子:
Input: arr[] = {3, 1, 6, 4, 5, 2}
Output: 60
Explanation:
The required maximum product can be obtained using subarray {6, 4, 5}
Therefore, maximum product = (6 + 4 + 5) * (4) = 60
Input: arr[] = {4, 1, 2, 9, 3}
Output: 81
Explanation:
The required maximum product can be obtained using subarray {9}
Maximum product = (9)* (9) = 81
天真的方法:解决问题的最简单方法是生成给定数组的所有子数组,并为每个子数组计算子数组的总和,然后将其与子数组中的最小元素相乘。通过将最大乘积与计算出的乘积进行比较来更新最大乘积。最后,打印处理所有子阵列后获得的最大乘积。
时间复杂度: O(N 3 )
辅助空间: O(1)
高效方法:可以使用堆栈和前缀和数组优化上述方法。这个想法是使用堆栈来获取每个元素左右两侧最近的较小元素的索引。现在,使用这些,可以获得所需的产品。请按照以下步骤解决问题:
- 初始化数组presum [],以存储给定数组的所有结果前缀和数组。
- 初始化两个数组l []和r []分别存储最近的左侧和右侧较小元素的索引。
- 对于每个元素arr [i] ,使用堆栈计算l [i]和r [i] 。
- 遍历给定的数组,对于每个索引i ,乘积可以通过以下公式计算:
arr[i] * (presum[r[i]] – presum[l[i]-1])
- 完成上述所有步骤后,打印最大数量的产品
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Function to find the
// maximum product possible
void maxValue(int a[], int n)
{
// Stores prefix sum
int presum[n];
presum[0] = a[0];
// Find the prefix sum array
for(int i = 1; i < n; i++)
{
presum[i] = presum[i - 1] + a[i];
}
// l[] and r[] stores index of
// nearest smaller elements on
// left and right respectively
int l[n], r[n];
stack st;
// Find all left index
for(int i = 1; i < n; i++)
{
// Until stack is non-empty
// & top element is greater
// than the current element
while (!st.empty() &&
a[st.top()] >= a[i])
st.pop();
// If stack is empty
if (!st.empty())
l[i] = st.top() + 1;
else
l[i] = 0;
// Push the current index i
st.push(i);
}
// Reset stack
while(!st.empty())
st.pop();
// Find all right index
for(int i = n - 1; i >= 0; i--)
{
// Until stack is non-empty
// & top element is greater
// than the current element
while (!st.empty() &&
a[st.top()] >= a[i])
st.pop();
if (!st.empty())
r[i] = st.top() - 1;
else
r[i] = n - 1;
// Push the current index i
st.push(i);
}
// Stores the maximum product
int maxProduct = 0;
int tempProduct;
// Iterate over the range [0, n)
for(int i = 0; i < n; i++)
{
// Calculate the product
tempProduct = a[i] * (presum[r[i]] -
(l[i] == 0 ? 0 :
presum[l[i] - 1]));
// Update the maximum product
maxProduct = max(maxProduct,
tempProduct);
}
// Return the maximum product
cout << maxProduct;
}
// Driver Code
int main()
{
// Given array
int n = 6;
int arr[] = { 3, 1, 6, 4, 5, 2 };
// Function call
maxValue(arr, n);
}
// This code is contributed by grand_master
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG {
// Function to find the
// maximum product possible
public static void
maxValue(int[] a, int n)
{
// Stores prefix sum
int[] presum = new int[n];
presum[0] = a[0];
// Find the prefix sum array
for (int i = 1; i < n; i++) {
presum[i] = presum[i - 1] + a[i];
}
// l[] and r[] stores index of
// nearest smaller elements on
// left and right respectively
int[] l = new int[n], r = new int[n];
Stack st = new Stack<>();
// Find all left index
for (int i = 1; i < n; i++) {
// Until stack is non-empty
// & top element is greater
// than the current element
while (!st.isEmpty()
&& a[st.peek()] >= a[i])
st.pop();
// If stack is empty
if (!st.isEmpty())
l[i] = st.peek() + 1;
else
l[i] = 0;
// Push the current index i
st.push(i);
}
// Reset stack
st.clear();
// Find all right index
for (int i = n - 1; i >= 0; i--) {
// Until stack is non-empty
// & top element is greater
// than the current element
while (!st.isEmpty()
&& a[st.peek()] >= a[i])
st.pop();
if (!st.isEmpty())
r[i] = st.peek() - 1;
else
r[i] = n - 1;
// Push the current index i
st.push(i);
}
// Stores the maximum product
int maxProduct = 0;
int tempProduct;
// Iterate over the range [0, n)
for (int i = 0; i < n; i++) {
// Calculate the product
tempProduct
= a[i]
* (presum[r[i]]
- (l[i] == 0 ? 0
: presum[l[i] - 1]));
// Update the maximum product
maxProduct
= Math.max(maxProduct,
tempProduct);
}
// Return the maximum product
System.out.println(maxProduct);
}
// Driver Code
public static void main(String[] args)
{
// Given array
int[] arr = { 3, 1, 6, 4, 5, 2 };
// Function Call
maxValue(arr, arr.length);
}
}
Python3
# Python3 program to implement
# the above approach
# Function to find the
# maximum product possible
def maxValue(a, n):
# Stores prefix sum
presum = [0 for i in range(n)]
presum[0] = a[0]
# Find the prefix sum array
for i in range(1, n, 1):
presum[i] = presum[i - 1] + a[i]
# l[] and r[] stores index of
# nearest smaller elements on
# left and right respectively
l = [0 for i in range(n)]
r = [0 for i in range(n)]
st = []
# Find all left index
for i in range(1, n):
# Until stack is non-empty
# & top element is greater
# than the current element
while (len(st) and
a[st[len(st) - 1]] >= a[i]):
st.remove(st[len(st) - 1])
# If stack is empty
if (len(st)):
l[i] = st[len(st) - 1] + 1;
else:
l[i] = 0
# Push the current index i
st.append(i)
# Reset stack
while(len(st)):
st.remove(st[len(st) - 1])
# Find all right index
i = n - 1
while(i >= 0):
# Until stack is non-empty
# & top element is greater
# than the current element
while (len(st) and
a[st[len(st) - 1]] >= a[i]):
st.remove(st[len(st) - 1])
if (len(st)):
r[i] = st[len(st) - 1] - 1
else:
r[i] = n - 1
# Push the current index i
st.append(i)
i -= 1
# Stores the maximum product
maxProduct = 0
# Iterate over the range [0, n)
for i in range(n):
# Calculate the product
if l[i] == 0:
tempProduct = (a[i] *
presum[r[i]])
else:
tempProduct = (a[i] *
(presum[r[i]] -
presum[l[i] - 1]))
# Update the maximum product
maxProduct = max(maxProduct,
tempProduct)
# Return the maximum product
print(maxProduct)
# Driver Code
if __name__ == '__main__':
# Given array
n = 6
arr = [ 3, 1, 6, 4, 5, 2 ]
# Function call
maxValue(arr, n)
# This code is contributed by SURENDRA_GANGWAR
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to find the
// maximum product possible
public static void maxValue(int[] a,
int n)
{
// Stores prefix sum
int[] presum = new int[n];
presum[0] = a[0];
// Find the prefix sum array
for(int i = 1; i < n; i++)
{
presum[i] = presum[i - 1] + a[i];
}
// l[] and r[] stores index of
// nearest smaller elements on
// left and right respectively
int[] l = new int[n], r = new int[n];
Stack st = new Stack();
// Find all left index
for(int i = 1; i < n; i++)
{
// Until stack is non-empty
// & top element is greater
// than the current element
while (st.Count > 0 &&
a[st.Peek()] >= a[i])
st.Pop();
// If stack is empty
if (st.Count > 0)
l[i] = st.Peek() + 1;
else
l[i] = 0;
// Push the current index i
st.Push(i);
}
// Reset stack
st.Clear();
// Find all right index
for(int i = n - 1; i >= 0; i--)
{
// Until stack is non-empty
// & top element is greater
// than the current element
while (st.Count > 0 &&
a[st.Peek()] >= a[i])
st.Pop();
if (st.Count > 0)
r[i] = st.Peek() - 1;
else
r[i] = n - 1;
// Push the current index i
st.Push(i);
}
// Stores the maximum product
int maxProduct = 0;
int tempProduct;
// Iterate over the range [0, n)
for(int i = 0; i < n; i++)
{
// Calculate the product
tempProduct = a[i] * (presum[r[i]] -
(l[i] == 0 ? 0 :
presum[l[i] - 1]));
// Update the maximum product
maxProduct = Math.Max(maxProduct,
tempProduct);
}
// Return the maximum product
Console.WriteLine(maxProduct);
}
// Driver code
static void Main()
{
// Given array
int[] arr = { 3, 1, 6, 4, 5, 2 };
// Function call
maxValue(arr, arr.Length);
}
}
// This code is contributed by divyeshrabadiya07
60
时间复杂度: O(N)
辅助空间: O(N)