📜  最大化严格增加或减少的子阵列的乘积

📅  最后修改于: 2021-05-14 00:57:36             🧑  作者: Mango

给定大小为N的数组arr [] ,任务是从包含严格按升序或降序顺序组成的元素的任何子数组中找到最大乘积。

例子:

天真的方法:解决此问题的最简单方法是从给定数组生成所有可能的子数组。对于每个子数组,检查子数组中存在的元素是否严格按照递增或递减的顺序排列。如果发现为真,则计算子数组元素的乘积。最后,打印获得的最大产品。

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

高效的方法可以通过遍历数组来优化上述方法,对于给定数组中每个递增或递减的子数组,都可以使用Kadane算法找到最大乘积。最后,打印增加或减少子阵列中所有乘积的最大值。请按照以下步骤解决问题:

  • 初始化一个变量,例如maxProd ,以存储给定数组中递增或递减子数组的最大可能乘积。
  • 遍历数组并计算最长的递增或递减的子数组,例如subarray [] ,其起始索引为i
  • 计算子阵列[]使用Kadane的算法的产品的最大乘积,说ProdSub和更新maxProd = MAX(maxProd,ProdSub)。
  • 最后,输出值maxProd

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to find the maximum product of
// subarray in the array, arr[]
int maxSubarrayProduct(vector arr, int n)
{
 
    // Maximum positive product
    // ending at the i-th index
    int max_ending_here = 1;
 
    // Minimum negative product ending
    // at the current index
    int min_ending_here = 1;
 
    // Maximum product up to
    // i-th index
    int max_so_far = 0;
 
    // Check if an array element
    // is positive or not
    int flag = 0;
 
    // Traverse the array
    for (int i = 0; i < n; i++) {
 
        // If current element
        // is positive
        if (arr[i] > 0) {
 
            // Update max_ending_here
            max_ending_here
                = max_ending_here * arr[i];
 
            // Update min_ending_here
            min_ending_here
                = min(min_ending_here * arr[i], 1);
 
            // Update flag
            flag = 1;
        }
 
        // If current element is 0, reset
        // the start index of subarray
        else if (arr[i] == 0) {
 
            // Update max_ending_here
            max_ending_here = 1;
 
            // Update min_ending_here
            min_ending_here = 1;
        }
 
        // If current element is negative
        else {
 
            // Stores max_ending_here
            int temp = max_ending_here;
 
            // Update max_ending_here
            max_ending_here
                = max(min_ending_here * arr[i], 1);
 
            // Update min_ending_here
            min_ending_here = temp * arr[i];
        }
 
        // Update max_so_far, if needed
        if (max_so_far < max_ending_here)
            max_so_far = max_ending_here;
    }
 
    // If no array elements is positive
    // and max_so_far is 0
    if (flag == 0 && max_so_far == 0)
        return 0;
    return max_so_far;
}
 
// Function to find the maximum product of either
// increasing subarray or the decreasing subarray
int findMaxProduct(int* a, int n)
{
 
    // Stores start index of either increasing
    // subarray or the decreasing subarray
    int i = 0;
 
    // Initially assume maxProd to be 1
    int maxProd = -1e9;
 
    // Traverse the array
    while (i < n) {
 
        // Store the longest either increasing
        // subarray or the decreasing subarray
        // whose start index is i
        vector v;
 
        v.push_back(a[i]);
 
        // Check for increasing subarray
        if (i < n - 1 && a[i] < a[i + 1]) {
 
            // Insert elements of
            // increasing subarray
            while (i < n - 1 && a[i] < a[i + 1]) {
                v.push_back(a[i + 1]);
                i += 1;
            }
        }
 
        // Check for decreasing subarray
        else if (i < n - 1 && a[i] > a[i + 1]) {
 
            // Insert elements of
            // decreasing subarray
            while (i < n - 1 && a[i] > a[i + 1]) {
                v.push_back(a[i + 1]);
                i += 1;
            }
        }
 
        // Stores maximum subarray product of
        // current increasing or decreasing
        // subarray
        int prod = maxSubarrayProduct(v, v.size());
 
        // Update maxProd
        maxProd = max(maxProd, prod);
 
        // Update i
        i++;
    }
 
    // Finally print maxProd
    return maxProd;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 2, 10, 8, 1, 100, 101 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    cout << findMaxProduct(arr, N);
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
class GFG
{
 
  // Function to find the maximum product of
  // subarray in the array, arr[]
  static int maxSubarrayProduct(Vector arr, int n)
  {
 
    // Maximum positive product
    // ending at the i-th index
    int max_ending_here = 1;
 
    // Minimum negative product ending
    // at the current index
    int min_ending_here = 1;
 
    // Maximum product up to
    // i-th index
    int max_so_far = 0;
 
    // Check if an array element
    // is positive or not
    int flag = 0;
 
    // Traverse the array
    for (int i = 0; i < n; i++)
    {
 
      // If current element
      // is positive
      if (arr.get(i) > 0)
      {
 
        // Update max_ending_here
        max_ending_here
          = max_ending_here * arr.get(i);
 
        // Update min_ending_here
        min_ending_here
          = Math.min(min_ending_here * arr.get(i), 1);
 
        // Update flag
        flag = 1;
      }
 
      // If current element is 0, reset
      // the start index of subarray
      else if (arr.get(i) == 0)
      {
 
        // Update max_ending_here
        max_ending_here = 1;
 
        // Update min_ending_here
        min_ending_here = 1;
      }
 
      // If current element is negative
      else
      {
 
        // Stores max_ending_here
        int temp = max_ending_here;
 
        // Update max_ending_here
        max_ending_here
          = Math.max(min_ending_here * arr.get(i), 1);
 
        // Update min_ending_here
        min_ending_here = temp * arr.get(i);
      }
 
      // Update max_so_far, if needed
      if (max_so_far < max_ending_here)
        max_so_far = max_ending_here;
    }
 
    // If no array elements is positive
    // and max_so_far is 0
    if (flag == 0 && max_so_far == 0)
      return 0;
    return max_so_far;
  }
 
  // Function to find the maximum product of either
  // increasing subarray or the decreasing subarray
  static int findMaxProduct(int[] a, int n)
  {
 
    // Stores start index of either increasing
    // subarray or the decreasing subarray
    int i = 0;
 
    // Initially assume maxProd to be 1
    int maxProd = 1;
 
    // Traverse the array
    while (i < n) {
 
      // Store the longest either increasing
      // subarray or the decreasing subarray
      // whose start index is i
      Vector v = new Vector<>();
 
      v.add(a[i]);
 
      // Check for increasing subarray
      if (i < n - 1 && a[i] < a[i + 1]) {
 
        // Insert elements of
        // increasing subarray
        while (i < n - 1 && a[i] < a[i + 1]) {
          v.add(a[i + 1]);
          i += 1;
        }
      }
 
      // Check for decreasing subarray
      else if (i < n - 1 && a[i] > a[i + 1]) {
 
        // Insert elements of
        // decreasing subarray
        while (i < n - 1 && a[i] > a[i + 1]) {
          v.add(a[i + 1]);
          i += 1;
        }
      }
 
      // Stores maximum subarray product of
      // current increasing or decreasing
      // subarray
      int prod = maxSubarrayProduct(v, v.size());
 
      // Update maxProd
      maxProd = Math.max(maxProd, prod);
 
      // Update i
      i++;
    }
 
    // Finally print maxProd
    return maxProd;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int arr[] = { 1, 2, 10, 8, 1, 100, 101 };
    int N = arr.length;
 
    System.out.print(findMaxProduct(arr, N));
  }
}
 
// This code contributed by gauravrajput1


Python3
# Python3 program to implement
# the above approach
 
# Function to find the maximum product
# of subarray in the array, arr[]
def maxSubarrayProduct(arr, n):
     
    # Maximum positive product
    # ending at the i-th index
    max_ending_here = 1
 
    # Minimum negative product ending
    # at the current index
    min_ending_here = 1
 
    # Maximum product up to
    # i-th index
    max_so_far = 0
 
    # Check if an array element
    # is positive or not
    flag = 0
 
    # Traverse the array
    for i in range(n):
         
        # If current element
        # is positive
        if (arr[i] > 0):
             
            # Update max_ending_here
            max_ending_here = max_ending_here * arr[i]
 
            # Update min_ending_here
            min_ending_here = min(
                min_ending_here * arr[i], 1)
 
            # Update flag
            flag = 1
 
        # If current element is 0, reset
        # the start index of subarray
        elif (arr[i] == 0):
             
            # Update max_ending_here
            max_ending_here = 1
             
            # Update min_ending_here
            min_ending_here = 1
             
        # If current element is negative
        else:
             
            # Stores max_ending_here
            temp = max_ending_here
 
            # Update max_ending_here
            max_ending_here = max(
                min_ending_here * arr[i], 1)
 
            # Update min_ending_here
            min_ending_here = temp * arr[i]
 
        # Update max_so_far, if needed
        if (max_so_far < max_ending_here):
            max_so_far = max_ending_here
 
    # If no array elements is positive
    # and max_so_far is 0
    if (flag == 0 and max_so_far == 0):
        return 0
         
    return max_so_far
 
# Function to find the maximum product
# of either increasing subarray or the
# decreasing subarray
def findMaxProduct(a, n):
     
    # Stores start index of either
    # increasing subarray or the
    # decreasing subarray
    i = 0
 
    # Initially assume maxProd to be 1
    maxProd = -10**9
 
    # Traverse the array
    while (i < n):
         
        # Store the longest either increasing
        # subarray or the decreasing subarray
        # whose start index is i
        v = []
 
        v.append(a[i])
 
        # Check for increasing subarray
        if i < n - 1 and a[i] < a[i + 1]:
             
            # Insert elements of
            # increasing subarray
            while (i < n - 1 and a[i] < a[i + 1]):
                v.append(a[i + 1])
                i += 1
 
        # Check for decreasing subarray
        elif (i < n - 1 and a[i] > a[i + 1]):
             
            # Insert elements of
            # decreasing subarray
            while (i < n - 1 and a[i] > a[i + 1]):
                v.append(a[i + 1])
                i += 1
 
        # Stores maximum subarray product of
        # current increasing or decreasing
        # subarray
        prod = maxSubarrayProduct(v, len(v))
 
        # Update maxProd
        maxProd = max(maxProd, prod)
 
        # Update i
        i += 1
 
    # Finally prmaxProd
    return maxProd
 
# Driver Code
if __name__ == '__main__':
     
    arr = [ 1, 2, 10, 8, 1, 100, 101 ]
    N = len(arr)
 
    print (findMaxProduct(arr, N))
 
# This code is contributed by mohit kumar 29


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
 
public class GFG
{
 
  // Function to find the maximum product of
  // subarray in the array, []arr
  static int maxSubarrayProduct(List arr, int n)
  {
 
    // Maximum positive product
    // ending at the i-th index
    int max_ending_here = 1;
 
    // Minimum negative product ending
    // at the current index
    int min_ending_here = 1;
 
    // Maximum product up to
    // i-th index
    int max_so_far = 0;
 
    // Check if an array element
    // is positive or not
    int flag = 0;
 
    // Traverse the array
    for (int i = 0; i < n; i++)
    {
 
      // If current element
      // is positive
      if (arr[i] > 0)
      {
 
        // Update max_ending_here
        max_ending_here
          = max_ending_here * arr[i];
 
        // Update min_ending_here
        min_ending_here
          = Math.Min(min_ending_here * arr[i], 1);
 
        // Update flag
        flag = 1;
      }
 
      // If current element is 0, reset
      // the start index of subarray
      else if (arr[i] == 0)
      {
 
        // Update max_ending_here
        max_ending_here = 1;
 
        // Update min_ending_here
        min_ending_here = 1;
      }
 
      // If current element is negative
      else
      {
 
        // Stores max_ending_here
        int temp = max_ending_here;
 
        // Update max_ending_here
        max_ending_here
          = Math.Max(min_ending_here * arr[i], 1);
 
        // Update min_ending_here
        min_ending_here = temp * arr[i];
      }
 
      // Update max_so_far, if needed
      if (max_so_far < max_ending_here)
        max_so_far = max_ending_here;
    }
 
    // If no array elements is positive
    // and max_so_far is 0
    if (flag == 0 && max_so_far == 0)
      return 0;
    return max_so_far;
  }
 
  // Function to find the maximum product of either
  // increasing subarray or the decreasing subarray
  static int findMaxProduct(int[] a, int n)
  {
 
    // Stores start index of either increasing
    // subarray or the decreasing subarray
    int i = 0;
 
    // Initially assume maxProd to be 1
    int maxProd = 1;
 
    // Traverse the array
    while (i < n) {
 
      // Store the longest either increasing
      // subarray or the decreasing subarray
      // whose start index is i
      List v = new List();
 
      v.Add(a[i]);
 
      // Check for increasing subarray
      if (i < n - 1 && a[i] < a[i + 1]) {
 
        // Insert elements of
        // increasing subarray
        while (i < n - 1 && a[i] < a[i + 1]) {
          v.Add(a[i + 1]);
          i += 1;
        }
      }
 
      // Check for decreasing subarray
      else if (i < n - 1 && a[i] > a[i + 1]) {
 
        // Insert elements of
        // decreasing subarray
        while (i < n - 1 && a[i] > a[i + 1]) {
          v.Add(a[i + 1]);
          i += 1;
        }
      }
 
      // Stores maximum subarray product of
      // current increasing or decreasing
      // subarray
      int prod = maxSubarrayProduct(v, v.Count);
 
      // Update maxProd
      maxProd = Math.Max(maxProd, prod);
 
      // Update i
      i++;
    }
 
    // Finally print maxProd
    return maxProd;
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    int []arr = { 1, 2, 10, 8, 1, 100, 101 };
    int N = arr.Length;
 
    Console.Write(findMaxProduct(arr, N));
  }
}
 
// This code is contributed by shikhasingrajput


输出:
10100

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