Source: https://leetcode.com/problems/maximum-product-subarray/
Given an integer array nums, find a contiguous non-empty subarray within the array that has the largest product, and return the product. The test cases are generated so that the answer will fit in a 32-bit integer. A subarray is a contiguous subsequence of the array.
/*** @param {number[]} nums* @return {number}*/// Cases to consider:// 0 i.e. [-2, 0, -1] => 0// Two negatives making a positive i.e. [2,-1,-10] -> 20// All negatives i.e. [-2,-1,-10] -> 10// Some positive and negatives [2,3,-2,4] -> 6// Only one number [1] => 1//// Brute force would be like O(N^3) time, O(1) space// Checking all possible subarrays i.e. from length 1 to n and finding the max from that// Or O(N^2) if we had nested loops to do the same thing i -> n and j starting at i to n and computing the prefix product along the way// Can't sort since order matters for contiguous non-empty subarray// Brainstorm:// [2,3,-2,4] => can prefixProduct [2,6,-12,-48] and/or suffixProduct [-48,-24,-8,4] help us find the answer?// It breaks if we have zeroes i.e. [2,0,5,0,4] => [2,0,0,0,0] or [4,0,0,0,0]// How about slightly modified prefixProduct and suffixProduct to account for zeroes and restarting the multiplier?// [-2,0,-1] => [-2,0,-1] and [-1,0,-2] => Max is 0// [4,0,5,2,0] => [4,0,5,10,0] and [0,2,10,0,4] => Max is 10// [2,-1,-10] => [2,-2,20] and [-10,10,20] => Max is 20// [-2,-1,-10] => [-2,2,-20] and [-10,10,-20] => Max is 10// O(N) time to compute modified prefix and suffix products and keep track of max with O(1) spacevar maxProduct = function(nums) {let max = -Infinity;// Compute modified prefix product and keep track of max seen so far// [4,0,5,2] => [4,0,5,10]// [2,-1,-10] => [2,-2,20]let currentProduct = 1;for (let i = 0; i < nums.length; i++) {const currentNum = nums[i];currentProduct *= currentNum;max = Math.max(max, currentProduct);// Whenever we multiply by zero, we reset the currentProduct back to 1 so we can continue to prefix multiply the restif (currentProduct === 0) {currentProduct = 1;}}// Compute modified suffix product and keep track of max seen so far// [4,0,5,2] => [2,10,0,4]// [2,-1,-10] => [-10,10,20]currentProduct = 1;for (let j = nums.length - 1; j > 0; j--) {const currentNum = nums[j];currentProduct *= currentNum;max = Math.max(max, currentProduct);// Whenever we encounter a zero, we reset the currentProduct back to 1 so we can continue to suffix multiply the restif (currentProduct === 0) {currentProduct = 1;}}return max;};