这道题与最大子串和有异曲同工之妙,但是要更难一点。最大子串和只需要一直往后累加,只要不会加到比原本小就继续累加,否则替换值。但是这题要更复杂一些,因为有可能会出现偶数个负数使最后的积变得更大,但是一直往后累乘是不可能出现与负数相乘的情况(因为相乘以后比本身小的情况会被替换值)。这个时候除了维护一个局部最大值外,还需维护一个局部最小值,并且每次都比较“局部最小值*子字符”与“局部最大值”两者的大小关系,这样就能保证局部最大值包含了偶数个负数出现导致最后的积变得更大的情况。简单的说,当出现负数时,局部最大值会被替换为子字符的值,而局部最小值=局部最大值*子字符,这样就能保证局部最小值一定是最小的,假如出现下一个负数,局部最大值就会被替换为局部最小值*子字符,保证时最大的乘积。
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))
class Solution {
public:
int maxProduct(vector<int>& nums) {
int size = nums.size();
if (!size)
return 0;
if (size == 1)
return nums[0];
int sum = nums[0];
int max = sum, min = sum;
for (int i = 1; i < size; i++) {
int tmp = sum;
sum = MAX(MAX(nums[i] * sum, nums[i]), nums[i] * min);
min = MIN(MIN(nums[i] * tmp, nums[i]), nums[i] * min);
max = MAX(max, sum);
}
return max;
}
};