Given an array a, we need to find the maximum product possible with the subset of elements present in the array.
- The maximum product can be of a single element also.
- Since the product can be large, return it modulo 109 + 7.
Input: a[] = [-1, -1, -2, 4, 3 ]
Output: 24
Explanation : Maximum product will be ( -2 * -1 * 4 * 3 ) = 24Input: a[] = [-1, 0]
Output: 0
Explanation: 0(single element) is maximum product possible
Table of Content
[Naive Approach] Generate All Subsets - O(2ⁿ) Time and O(n) Space
The idea is to recursively generate every possible non-empty subsequence of the array. For each element, there are two choices: either include it in the current subsequence or exclude it. While exploring all possible combinations, the product of the selected elements is maintained. Whenever the end of the array is reached, the product of the current non-empty subsequence is compared with the maximum product found so far.
- Start recursion from index
0 - Consider two choices for every element: Include it in the subsequence and Exclude it from the subsequence
- Maintain the product of selected elements
- When all elements are processed, If the subsequence is non-empty, update the maximum product
- Return the maximum product found
#include <bits/stdc++.h>
using namespace std;
void solve(int idx, vector<int> &arr,
long long prod, bool taken, long long &ans) {
// Reached end of array
if (idx == arr.size())
{
if (taken)
{
ans = max(ans, prod);
}
return;
}
// Include current element
solve(idx + 1, arr, prod * arr[idx], true, ans);
// Exclude current element
solve(idx + 1, arr, prod, taken, ans);
}
int findMaxProduct(vector<int> &arr)
{
long long ans = LLONG_MIN;
solve(0, arr, 1, false, ans);
return (int)ans;
}
int main() {
vector<int> arr = {-1, -1, -2, 4, 3};
cout << findMaxProduct(arr);
return 0;
}
import java.util.*;
class GfG {
static void solve(int idx, int[] arr,
long prod, boolean taken, long[] ans) {
// Reached end of array
if (idx == arr.length) {
if (taken) {
ans[0] = Math.max(ans[0], prod);
}
return;
}
// Include current element
solve(idx + 1, arr, prod * arr[idx], true, ans);
// Exclude current element
solve(idx + 1, arr, prod, taken, ans);
}
static int findMaxProduct(int[] arr) {
long[] ans = {Long.MIN_VALUE};
solve(0, arr, 1, false, ans);
return (int)ans[0];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // size of array
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
System.out.println(findMaxProduct(arr));
sc.close();
}
}
# Python program to find maximum product of any subset using recursion
def solve(idx, arr, prod, taken, ans):
# Reached end of array
if idx == len(arr):
if taken:
ans[0] = max(ans[0], prod)
return
# Include current element
solve(idx + 1, arr, prod * arr[idx], True, ans)
# Exclude current element
solve(idx + 1, arr, prod, taken, ans)
def findMaxProduct(arr):
ans = [float('-inf')]
solve(0, arr, 1, False, ans)
return ans[0]
if __name__ == "__main__":
arr = [-1, -1, -2, 4, 3]
print(findMaxProduct(arr))
using System;
class GfG
{
static void Solve(int idx, int[] arr, long prod, bool taken, ref long ans)
{
// Reached end of array
if (idx == arr.Length)
{
if (taken)
{
ans = Math.Max(ans, prod);
}
return;
}
// Include current element
Solve(idx + 1, arr, prod * arr[idx], true, ref ans);
// Exclude current element
Solve(idx + 1, arr, prod, taken, ref ans);
}
static int FindMaxProduct(int[] arr)
{
long ans = long.MinValue;
Solve(0, arr, 1, false, ref ans);
return (int)ans;
}
public static void Main()
{
int[] arr = { -1, -1, -2, 4, 3 };
Console.WriteLine(FindMaxProduct(arr));
}
}
// JavaScript program to find maximum product of any subset using recursion
function solve(idx, arr, prod, taken, ans) {
// Reached end of array
if (idx === arr.length) {
if (taken) {
ans[0] = Math.max(ans[0], prod);
}
return;
}
// Include current element
solve(idx + 1, arr, prod * arr[idx], true, ans);
// Exclude current element
solve(idx + 1, arr, prod, taken, ans);
}
function findMaxProduct(arr) {
let ans = [-Infinity];
solve(0, arr, 1, false, ans);
return ans[0];
}
// Driver code
const arr = [-1, -1, -2, 4, 3];
console.log(findMaxProduct(arr));
Output
24
[Expected Approach] Using Greedy Traversal - O(n) Time and O(1) Space
The idea is to count the occurrence of positive and negative elements.
- If there are even number of negative numbers and no zeros, the result is simply the product of all
- If there are odd number of negative numbers and no zeros, then the result is the product of all except the negative integer with the least absolute value or maximum value among all negatives.
- If there are zeros, the result is computed same way as above ignoring zeros except one case. The exceptional case is when there is one negative number and all other elements are 0. In this case, the result is 0.
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int findMaxProduct(vector<int>& arr) {
int n = arr.size();
// If only one element
if (n == 1) return arr[0];
long long ans = 1;
int mod = 1e9 + 7;
int zeroCount = 0, negCount = 0;
int maxNeg = INT_MIN, idxMaxNeg = -1;
// Count zeros and negatives
for (int i = 0; i < n; i++) {
if (arr[i] == 0) {
zeroCount++;
}
else if (arr[i] < 0) {
negCount++;
if (idxMaxNeg == -1 || arr[i] > maxNeg) {
maxNeg = arr[i];
idxMaxNeg = i;
}
}
}
// Edge cases
if (zeroCount == n) return 0;
if (negCount == 1 && zeroCount == n - 1) return 0;
// Calculate product
for (int i = 0; i < n; i++) {
if (arr[i] == 0) continue;
// Skip one negative if count is odd
if (negCount % 2 == 1 && i == idxMaxNeg) continue;
ans = ((ans * arr[i]) % mod + mod) % mod;
}
return ans;
}
// Driver Code
int main() {
vector<int> arr = { -1, -1, -2, 4, 3 };
cout << findMaxProduct(arr);
return 0;
}
#include <stdio.h>
#include <limits.h>
int findMaxProduct(int arr[], int n) {
// If only one element
if (n == 1) return arr[0];
long long ans = 1;
int mod = 1000000007;
int zeroCount = 0, negCount = 0;
int maxNeg = INT_MIN, idxMaxNeg = -1;
// Count zeros and negatives
for (int i = 0; i < n; i++) {
if (arr[i] == 0) {
zeroCount++;
}
else if (arr[i] < 0) {
negCount++;
if (idxMaxNeg == -1 || arr[i] > maxNeg) {
maxNeg = arr[i];
idxMaxNeg = i;
}
}
}
// Edge cases
if (zeroCount == n) return 0;
if (negCount == 1 && zeroCount == n - 1) return 0;
// Calculate product
for (int i = 0; i < n; i++) {
if (arr[i] == 0) continue;
// Skip one negative if count is odd
if (negCount % 2 == 1 && i == idxMaxNeg) continue;
ans = ((ans * arr[i]) % mod + mod) % mod;
}
return (int)ans;
}
// Driver Code
int main() {
int arr[] = { -1, -1, -2, 4, 3 };
int n = sizeof(arr) / sizeof(arr[0]);
printf("%d", findMaxProduct(arr, n));
return 0;
}
import java.util.*;
class GFG {
static int findMaxProduct(int[] arr) {
int n = arr.length;
// If only one element
if (n == 1) return arr[0];
long ans = 1;
int mod = (int)1e9 + 7;
int zeroCount = 0, negCount = 0;
int maxNeg = Integer.MIN_VALUE, idxMaxNeg = -1;
// Count zeros and negatives
for (int i = 0; i < n; i++) {
if (arr[i] == 0) {
zeroCount++;
}
else if (arr[i] < 0) {
negCount++;
if (idxMaxNeg == -1 || arr[i] > maxNeg) {
maxNeg = arr[i];
idxMaxNeg = i;
}
}
}
// Edge cases
if (zeroCount == n) return 0;
if (negCount == 1 && zeroCount == n - 1) return 0;
// Calculate product
for (int i = 0; i < n; i++) {
if (arr[i] == 0) continue;
// Skip one negative if count is odd
if (negCount % 2 == 1 && i == idxMaxNeg) continue;
ans = ((ans * arr[i]) % mod + mod) % mod;
}
return (int)ans;
}
public static void main(String[] args) {
int[] arr = { -1, -1, -2, 4, 3 };
System.out.println(findMaxProduct(arr));
}
}
# Function to find maximum product subset
def findMaxProduct(arr):
n = len(arr)
# If only one element
if n == 1:
return arr[0]
ans = 1
mod = 10**9 + 7
zeroCount = 0
negCount = 0
maxNeg = float('-inf')
idxMaxNeg = -1
# Count zeros and negatives
for i in range(n):
if arr[i] == 0:
zeroCount += 1
elif arr[i] < 0:
negCount += 1
if idxMaxNeg == -1 or arr[i] > maxNeg:
maxNeg = arr[i]
idxMaxNeg = i
# Edge cases
if zeroCount == n:
return 0
if negCount == 1 and zeroCount == n - 1:
return 0
# Calculate product
for i in range(n):
if arr[i] == 0:
continue
# Skip one negative if count is odd
if negCount % 2 == 1 and i == idxMaxNeg:
continue
ans = ((ans * arr[i]) % mod + mod) % mod
return ans
if __name__ == "__main__":
arr = [ -1, -1, -2, 4, 3 ]
print(findMaxProduct(arr))
using System;
class GFG {
static int findMaxProduct(int[] arr) {
int n = arr.Length;
// If only one element
if (n == 1) return arr[0];
long ans = 1;
int mod = (int)1e9 + 7;
int zeroCount = 0, negCount = 0;
int maxNeg = int.MinValue, idxMaxNeg = -1;
// Count zeros and negatives
for (int i = 0; i < n; i++) {
if (arr[i] == 0) {
zeroCount++;
}
else if (arr[i] < 0) {
negCount++;
if (idxMaxNeg == -1 || arr[i] > maxNeg) {
maxNeg = arr[i];
idxMaxNeg = i;
}
}
}
// Edge cases
if (zeroCount == n) return 0;
if (negCount == 1 && zeroCount == n - 1) return 0;
// Calculate product
for (int i = 0; i < n; i++) {
if (arr[i] == 0) continue;
// Skip one negative if count is odd
if (negCount % 2 == 1 && i == idxMaxNeg) continue;
ans = ((ans * arr[i]) % mod + mod) % mod;
}
return (int)ans;
}
public static void Main() {
int[] arr = { -1, -1, -2, 4, 3 };
Console.WriteLine(findMaxProduct(arr));
}
}
// Function to find maximum product subset
function findMaxProduct(arr) {
let n = arr.length;
// If only one element
if (n === 1) return arr[0];
let ans = 1;
let mod = 1e9 + 7;
let zeroCount = 0, negCount = 0;
let maxNeg = Number.MIN_SAFE_INTEGER, idxMaxNeg = -1;
// Count zeros and negatives
for (let i = 0; i < n; i++) {
if (arr[i] === 0) {
zeroCount++;
} else if (arr[i] < 0) {
negCount++;
if (idxMaxNeg === -1 || arr[i] > maxNeg) {
maxNeg = arr[i];
idxMaxNeg = i;
}
}
}
// Edge cases
if (zeroCount === n) return 0;
if (negCount === 1 && zeroCount === n - 1) return 0;
// Calculate product
for (let i = 0; i < n; i++) {
if (arr[i] === 0) continue;
// Skip one negative if count is odd
if (negCount % 2 === 1 && i === idxMaxNeg) continue;
ans = ((ans * arr[i]) % mod + mod) % mod;
}
return ans;
}
// Driver Code
let arr = [ -1, -1, -2, 4, 3 ];
console.log(findMaxProduct(arr));
Output
24