feat-Add MaximumProductSubarray (#6711)

* feat-Add MaximumProductSubarray

* feat-changes

* fix: correct MaximumProductSubarray compilation errors

* fix-lints

* fix: apply clang-format to MaximumProductSubarrayTest.java

* fix: prevent integer overflow in MaximumProductSubarray using long type
This commit is contained in:
Sachin Pangal
2025-10-09 12:42:51 +05:30
committed by GitHub
parent 4fe37c3a10
commit e22ce0005e
2 changed files with 210 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
package com.thealgorithms.dynamicprogramming;
/**
* The MaximumProductSubarray class implements the algorithm to find the
* maximum product of a contiguous subarray within a given array of integers.
*
* <p>Given an array of integers (which may contain positive numbers, negative
* numbers, and zeros), this algorithm finds the contiguous subarray that has
* the largest product. The algorithm handles negative numbers efficiently by
* tracking both maximum and minimum products, since a negative number can turn
* a minimum product into a maximum product.</p>
*
* <p>This implementation uses a dynamic programming approach that runs in O(n)
* time complexity and O(1) space complexity, making it highly efficient for
* large arrays.</p>
*/
public final class MaximumProductSubarray {
private MaximumProductSubarray() {
// Prevent instantiation
}
/**
* Finds the maximum product of any contiguous subarray in the given array.
*
* @param nums an array of integers which may contain positive, negative,
* and zero values.
* @return the maximum product of a contiguous subarray. Returns 0 if the
* array is null or empty.
*/
public static int maxProduct(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
long maxProduct = nums[0];
long currentMax = nums[0];
long currentMin = nums[0];
for (int i = 1; i < nums.length; i++) {
// Swap currentMax and currentMin if current number is negative
if (nums[i] < 0) {
long temp = currentMax;
currentMax = currentMin;
currentMin = temp;
}
// Update currentMax and currentMin
currentMax = Math.max(nums[i], currentMax * nums[i]);
currentMin = Math.min(nums[i], currentMin * nums[i]);
// Update global max product
maxProduct = Math.max(maxProduct, currentMax);
}
return (int) maxProduct;
}
}

View File

@@ -0,0 +1,152 @@
package com.thealgorithms.dynamicprogramming;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
class MaximumProductSubarrayTest {
/**
* Test case for an array with all positive numbers.
* The expected maximum product is the product of all elements.
*/
@Test
void testAllPositiveNumbers() {
int[] nums = {2, 3, 4};
int expected = 24;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be 24.");
}
/**
* Test case for an array with positive and negative numbers.
* The expected maximum product is 24 (subarray [2, -3, -4]).
*/
@Test
void testMixedPositiveAndNegative() {
int[] nums = {2, -3, -4, 1};
int expected = 24;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be 24.");
}
/**
* Test case for an array containing zeros.
* The expected maximum product is 24 (subarray [4, 6]).
*/
@Test
void testArrayWithZeros() {
int[] nums = {2, 3, 0, 4, 6};
int expected = 24;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be 24.");
}
/**
* Test case for an array with a single element.
* The expected maximum product is the element itself.
*/
@Test
void testSingleElement() {
int[] nums = {5};
int expected = 5;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be 5.");
}
/**
* Test case for an array with all negative numbers.
* The expected maximum product is 12 (subarray [-3, -4]).
*/
@Test
void testAllNegativeNumbers() {
int[] nums = {-2, -3, -4};
int expected = 12;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be 12.");
}
/**
* Test case for an array with negative numbers where odd count of negatives
* breaks the chain. The expected maximum product is 60 (subarray [-2, -3, 10]).
*/
@Test
void testOddNegativeNumbers() {
int[] nums = {-2, -3, 10, -1};
int expected = 60;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be 60.");
}
/**
* Test case for an empty array.
* The expected maximum product is 0.
*/
@Test
void testEmptyArray() {
int[] nums = {};
int expected = 0;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be 0 for an empty array.");
}
/**
* Test case for a null array.
* The expected maximum product is 0.
*/
@Test
void testNullArray() {
int[] nums = null;
int expected = 0;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be 0 for a null array.");
}
/**
* Test case for an array with alternating positive and negative numbers.
* The expected maximum product is 6 (subarray [2, 3]).
*/
@Test
void testAlternatingNumbers() {
int[] nums = {2, 3, -2, 4};
int expected = 6;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be 6.");
}
/**
* Test case for an array with large positive and negative numbers.
* The expected maximum product is 360 (subarray [6, -3, -20]).
*/
@Test
void testLargeNumbers() {
int[] nums = {6, -3, -20, 0, 5};
int expected = 360;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be 360.");
}
/**
* Test case for an array with single negative number.
* The expected maximum product is the negative number itself.
*/
@Test
void testSingleNegativeElement() {
int[] nums = {-8};
int expected = -8;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be -8.");
}
/**
* Test case for an array with multiple zeros.
* The expected maximum product is 6 (subarray [2, 3]).
*/
@Test
void testMultipleZeros() {
int[] nums = {0, 2, 3, 0, 4};
int expected = 6;
int actual = MaximumProductSubarray.maxProduct(nums);
assertEquals(expected, actual, "The maximum product should be 6.");
}
}