📜  数组的最大乘积子集

📅  最后修改于: 2021-05-04 12:37:41             🧑  作者: Mango

给定一个数组a,我们必须找到数组中存在的元素子集的最大乘积。最大乘积也可以是单个元素。
例子:

Input: a[] = { -1, -1, -2, 4, 3 }
Output: 24
Explanation : Maximum product will be ( -2 * -1 * 4 * 3 ) = 24

Input: a[] = { -1, 0 }
Output: 0
Explanation: 0(single element) is maximum product possible
 
Input: a[] = { 0, 0, 0 }
Output: 0

一个简单的解决方案是生成所有子集,找到每个子集的乘积并返回最大乘积。
更好的解决方案是使用以下事实。

  1. 如果负数为偶数且不为零,则结果仅是所有数的乘积
  2. 如果负数的个数为奇数且不为零,则结果为除具有最小绝对值的负整数以外的所有结果的乘积。
  3. 如果为零,则结果是除这些零以外的所有结果的乘积,其中有一种例外情况。例外情况是当负数为1且所有其他元素均为0时。在这种情况下,结果为0。

下面是上述方法的实现:

C++
// CPP program to find maximum product of
// a subset.
#include 
using namespace std;
 
int maxProductSubset(int a[], int n)
{
    if (n == 1)
        return a[0];
 
    // Find count of negative numbers, count
    // of zeros, negative number
    // with least absolute value
    // and product of non-zero numbers
    int max_neg = INT_MIN;
    int count_neg = 0, count_zero = 0;
    int prod = 1;
    for (int i = 0; i < n; i++) {
 
        // If number is 0, we don't
        // multiply it with product.
        if (a[i] == 0) {
            count_zero++;
            continue;
        }
 
        // Count negatives and keep
        // track of negative number
        // with least absolute value
        if (a[i] < 0) {
            count_neg++;
            max_neg = max(max_neg, a[i]);
        }
 
        prod = prod * a[i];
    }
 
    // If there are all zeros
    if (count_zero == n)
        return 0;
 
    // If there are odd number of
    // negative numbers
    if (count_neg & 1) {
 
        // Exceptional case: There is only
        // negative and all other are zeros
        if (count_neg == 1 &&
            count_zero > 0 &&
            count_zero + count_neg == n)
            return 0;
 
        // Otherwise result is product of
        // all non-zeros divided by
        //negative number with
        // least absolute value
        prod = prod / max_neg;
    }
 
    return prod;
}
 
// Driver Code
int main()
{
    int a[] = {  -1, -1, -2, 4, 3  };
    int n = sizeof(a) / sizeof(a[0]);
    cout << maxProductSubset(a, n);
    return 0;
}


Java
// Java program to find maximum product of
// a subset.
 
class GFG {
 
    static int maxProductSubset(int a[], int n) {
        if (n == 1) {
            return a[0];
        }
 
        // Find count of negative numbers, count
        // of zeros, negative number
        // with least absolute value
        // and product of non-zero numbers
        int max_neg = Integer.MIN_VALUE;
        int count_neg = 0, count_zero = 0;
        int prod = 1;
        for (int i = 0; i < n; i++) {
 
            // If number is 0, we don't
            // multiply it with product.
            if (a[i] == 0) {
                count_zero++;
                continue;
            }
 
            // Count negatives and keep
            // track of negative number
            // with least absolute value.
            if (a[i] < 0) {
                count_neg++;
                max_neg = Math.max(max_neg, a[i]);
            }
 
            prod = prod * a[i];
        }
 
        // If there are all zeros
        if (count_zero == n) {
            return 0;
        }
 
        // If there are odd number of
        // negative numbers
        if (count_neg % 2 == 1) {
 
            // Exceptional case: There is only
            // negative and all other are zeros
            if (count_neg == 1
                    && count_zero > 0
                    && count_zero + count_neg == n) {
                return 0;
            }
 
            // Otherwise result is product of
            // all non-zeros divided by
            //negative number with
            // least absolute value.
            prod = prod / max_neg;
        }
 
        return prod;
    }
 
    // Driver Code
    public static void main(String[] args) {
        int a[] = {-1, -1, -2, 4, 3};
        int n = a.length;
        System.out.println(maxProductSubset(a, n));
 
    }
}
/* This JAVA code is contributed by Rajput-Ji*/


Python3
# Python3 program to find maximum product
# of a subset.
 
def maxProductSubset(a, n):
    if n == 1:
        return a[0]
 
    # Find count of negative numbers, count
    # of zeros, negative number
    # with least absolute value
    # and product of non-zero numbers
    max_neg = -999999999999
    count_neg = 0
    count_zero = 0
    prod = 1
    for i in range(n):
 
        # If number is 0, we don't
        # multiply it with product.
        if a[i] == 0:
            count_zero += 1
            continue
 
        # Count negatives and keep
        # track of negative number
        # with least absolute value.
        if a[i] < 0:
            count_neg += 1
            max_neg = max(max_neg, a[i])
 
        prod = prod * a[i]
 
    # If there are all zeros
    if count_zero == n:
        return 0
 
    # If there are odd number of
    # negative numbers
    if count_neg & 1:
 
        # Exceptional case: There is only
        # negative and all other are zeros
        if (count_neg == 1 and count_zero > 0 and
            count_zero + count_neg == n):
            return 0
 
        # Otherwise result is product of
        # all non-zeros divided
        # by negative number
        # with least absolute value
        prod = int(prod / max_neg)
 
    return prod
 
# Driver Code
if __name__ == '__main__':
    a = [ -1, -1, -2, 4, 3 ]
    n = len(a)
    print(maxProductSubset(a, n))
 
# This code is contributed by PranchalK


C#
// C# Java program to find maximum
// product of a subset.
using System;
                     
class GFG
{
 
static int maxProductSubset(int []a,
                            int n)
{
    if (n == 1)
    {
        return a[0];
    }
 
    // Find count of negative numbers,
    // count of zeros, negative number with
    // least absolute value and product of
    // non-zero numbers
    int max_neg = int.MinValue;
    int count_neg = 0, count_zero = 0;
    int prod = 1;
    for (int i = 0; i < n; i++)
    {
 
        // If number is 0, we don't
        // multiply it with product.
        if (a[i] == 0)
        {
            count_zero++;
            continue;
        }
 
        // Count negatives and keep
        // track of negative number with
        // least absolute value.
        if (a[i] < 0)
        {
            count_neg++;
            max_neg = Math.Max(max_neg, a[i]);
        }
 
        prod = prod * a[i];
    }
 
    // If there are all zeros
    if (count_zero == n)
    {
        return 0;
    }
 
    // If there are odd number of
    // negative numbers
    if (count_neg % 2 == 1)
    {
 
        // Exceptional case: There is only
        // negative and all other are zeros
        if (count_neg == 1 && count_zero > 0 &&
            count_zero + count_neg == n)
        {
            return 0;
        }
 
        // Otherwise result is product of
        // all non-zeros divided by negative
        // number with least absolute value.
        prod = prod / max_neg;
    }
 
    return prod;
}
 
// Driver code
public static void Main()
{
    int []a = {-1, -1, -2, 4, 3};
    int n = a.Length;
    Console.Write(maxProductSubset(a, n));
}
}
 
// This code is contributed by Rajput-Ji


PHP
 0 &&
            $count_zero + $count_neg == $n)
            return 0;
 
        // Otherwise result is product of
        // all non-zeros divided by negative
        // number with least absolute value.
        $prod = $prod / $max_neg;
    }
 
    return $prod;
}
 
// Driver Code
$a = array(-1, -1, -2, 4, 3 );
$n = sizeof($a);
echo maxProductSubset($a, $n);
 
// This code is contributed
// by Akanksha Rai
?>


输出
24

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