📌  相关文章
📜  用最小元素最大化子数组和的乘积

📅  最后修改于: 2021-05-17 23:03:37             🧑  作者: Mango

给定一个由N个正整数组成的数组arr [] ,任务是找到子数组和与该子数组的最小元素的最大乘积。

例子:

天真的方法:解决问题的最简单方法是生成给定数组的所有子数组,并为每个子数组计算子数组的总和,然后将其与子数组中的最小元素相乘。通过将最大乘积与计算出的乘积进行比较来更新最大乘积。最后,打印处理所有子阵列后获得的最大乘积。

时间复杂度: O(N 3 )
辅助空间: O(1)

高效方法:可以使用堆栈和前缀和数组优化上述方法。这个想法是使用堆栈来获取每个元素左右两侧最近的较小元素的索引。现在,使用这些,可以获得所需的产品。请按照以下步骤解决问题:

  • 初始化数组presum [],以存储给定数组的所有结果前缀和数组。
  • 初始化两个数组l []r []分别存储最近的左侧和右侧较小元素的索引。
  • 对于每个元素arr [i] ,使用堆栈计算l [i]r [i]
  • 遍历给定的数组,对于每个索引i ,乘积可以通过以下公式计算:
  • 完成上述所有步骤后,打印最大数量的产品

下面是上述方法的实现:

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)