给定一个由N 个正整数组成的数组arr[] ,任务是找到子数组 sum 与该子数组的最小元素的最大乘积。
例子:
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
Javascript
60
时间复杂度: O(N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live