Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4]
,
the contiguous subarray [2,3]
has the largest product = 6
.
算法一,
维持2个累乘变量,一个最大值,一个最小值。
之所以同时维持一个最小值,是因为遇到一个负数时,最小值,就可能变成最大值。
同时需要考虑的是0的影响,即0会将累乘值变成0. 故局部最大、小值时,也有可能在当前元素的值取得,而不仅是在累乘值中取得。
此代码在leetcode上实际执行时间为8ms。
class Solution { public: int maxProduct(vector<int>& nums) { int local_max = 1; int local_min = 1; int ans = INT_MIN; for (int i=0; i<nums.size(); i++) { const int temp1 = local_max * nums[i]; const int temp2 = local_min * nums[i]; local_max = max(max(temp1, temp2), nums[i]); local_min = min(min(temp1, temp2), nums[i]); ans = max(ans, local_max); } return ans; } };
算法二,
从前向后作一次累乘;
再作一次从向向前累乘。
记录累乘出现过的最大值。
算法分析:
数值0,将会使累乘清0.故值0会将数组分隔成各个独立的小单元。累乘值的最大值,将在各个小单元内取得。
而变数最大的为负数。
先将所有正数略去,即全是负数。 则要取得最值,分以下几种cases:
1. 如果负数个数为偶数,则全部相乘。
2. 如果负数个数为奇数,则累乘最大值, 将从2种cases取得,即不要第一个负数,或者不要最后一个负数。
而正数的填塞期间,并不影响到上面的case。同时也不会增加新的case。
累乘变量,从前向后乘,将能涵盖,不要最后一个负数的情况。而从后向前累乘,则能涵盖,不要第一个负数的情况。
另外不论是从前向后,或者从后向前,都能涵盖,全体相乘的情况。
此代码在leetcode上实际执行时间为4ms。
class Solution { public: int maxProduct(vector<int>& nums) { const int n = nums.size(); int ans = INT_MIN; int front = 0; int back = 0; for (int i=0; i<n; i++) { front = front ? front*nums[i] : nums[i]; back = back ? back*nums[n-1-i] : nums[n-1-i]; ans = max(ans, max(front, back)); } return ans; } };
Maximum Product Subarray -- leetcode
原文地址:http://blog.csdn.net/elton_xiao/article/details/46490321