In this post, we will explore the process of identifying the largest product subarray in C++.
Calculate the maximum product of a subarray containing both positive and negative integers within the provided array. The expected time complexity for this operation is O(n), and it should be achieved using only O(1) additional space.
Examples:
Input: arr[] = {4, -5, -6, 0, 2}
Output: 120 // The subarray is {4, -5, -6}
Input: arr[] = {-5, -10, -2, 0, 60}
Output: 0 // The subarray is {0}
Input: arr[] = {-10, -3, 0, -5, -4}
Output: 12 // The subarray is {-3, -4}
Naive Solution:
The objective involves scanning through consecutive subarrays, calculating the product of each subarray, and ultimately identifying the maximum product among these results.
Program:
Let's consider an illustration to showcase the process of identifying the largest product subarray in C++:
// C++ program to find Maximum Product Subarray
#include <bits/stdc++.h>
using namespace std;
int maxSubarrayProduct(int arr[], int n)
{
int result = arr[0];
for (int i = 0; i < n; i++)
{
int mul = arr[i];
for (int j = i + 1; j < n; j++)
{
result = max(result, mul);
mul *= arr[j];
}
// updating the result for (n-1)th index.
result = max(result, mul);
}
return result;
}
int main()
{
int arr[] = {4, -5, -6, 0, 2, -8, -2 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Maximum Sub array product is "<< maxSubarrayProduct(arr, n);
return 0;
}
Output:
Complexity:
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Solution:
Program:
#include <bits/stdc++.h>
using namespace std;
int maxSubarrayProduct(int arr[], int n)
{
int max_ending_here = 1;
int min_ending_here = 1;
int max_so_far = 0;
int flag = 0;
for (int i = 0; i < n; i++)
{
if (arr[i] > 0)
{
max_ending_here = max_ending_here * arr[i];
min_ending_here = min(min_ending_here * arr[i], 1);
flag = 1;
}
else if (arr[i] == 0) {
max_ending_here = 1;
min_ending_here = 1;
}
else {
int temp = max_ending_here;
max_ending_here = max(min_ending_here * arr[i], 1);
min_ending_here = temp * arr[i];
}
if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
}
if (flag == 0 && max_so_far == 0)
return 0;
return max_so_far;
}
int main()
{
int arr[] = {4, -5, -6, 0, 2, -8, -2 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Maximum Sub array product is "<< maxSubarrayProduct(arr, n);
return 0;
}
Output:
Complexity:
Time Complexity: O(n)
Auxiliary Space: O(1)
Benefits of Maximum product subarray:
There are numerous advantages associated with implementing the Maximum Product Subarray algorithm in C++. Some key benefits of utilizing the Maximum Product Subarray technique in C++ include:
Efficiency: Resolving the Maximum Product Subarray issue in C++ can be done effectively. Dynamic programming or two-pointer techniques can be utilized to achieve optimal time complexity.
Flexibility: Implementing the Maximum Product Subarray issue in C++ allows for a range of options when it comes to data structures and tools. You have the flexibility to use arrays, vectors, or other data structures to process the input data and calculate the maximum product with efficiency.
Standard Template Library (STL): The problem of finding the maximum product subarray can be simplified with the assistance of the Standard Template Library (STL) in C++. This library offers a range of useful data structures and algorithms. For example, you can streamline your code by leveraging the std::vector and std::max functions.
Performance Enhancement: In C++, you have the ability to enhance the speed of your code. By leveraging inline assembly and compiler optimizations, you can improve the execution time, which is essential for tackling complex problem scenarios.
Portability: C++ is a commonly utilized and versatile language, facilitating the development of applications that can function seamlessly across diverse systems. It is essential for software intended to run on a range of environments and platforms to possess portability.
Maintainability: Solving the Maximum Product Subarray issue involves leveraging C++'s strengths in object-oriented programming to create clear and maintainable code. Utilizing classes and structures allows for a more organized and easier-to-understand codebase, facilitating future updates and modifications.