题目
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.
题目解析
这是一个找集合中连续数相乘最大值的问题
思路解析
传统的解法就是两层for循环找到连续数相乘最大值,复杂度为o(n^2),但是可以通过动态规划去优化。就举题目的例子作为讨论,因为我们要返回集合中连续数相乘最大值,用TrueMax代替,遍历数组时候的最大值就用Max去代替。
如果单单从题目的例子,似乎我们很简单得到动态方程, Truemax = max(max, max*nums[i]),但这样未免考虑太不周到了,如果在题目的基础上再加一些数,比如[2,3,-2,4,5,-7],那么根据这个简单的动态方程就会得不到正确的结果,关键的地方在于但没有考虑负数可以连乘的情况,因此我们还要去设置Min去记录遍历过程中的最小值。考虑到负数相乘Min可能会变成Max的情况,我们得到动态方程:
Max = max(nums[i], max(partmax, partmin));
Min = std::min(nums[i], std::min(partmax, partmin));
注:partmax = Max * nums[i], partmin = Min * nums[i], 这里为什么要与nums[i]去比较最大与最小呢?试想一下这个例子[0,2],如果没有跟nums[i]去比较,那么结果就会返回0,而不是2
AC代码
class Solution {
public:
int maxProduct(vector<int>& nums) {
if (nums.size() == 1) return nums[0];
else if (nums.size() > 1) {
int Max, Min, TrueMax;
TrueMax = Max = Min = nums[0];
for (int i = 1; i < nums.size(); ++i) {
int partmax = Max * nums[i], partmin = Min * nums[i];
Max = std::max(nums[i], std::max(partmax, partmin));
Min = std::min(nums[i], std::min(partmax, partmin));
TrueMax = std::max(TrueMax, Max);
}
return TrueMax;
}
return 0;
}
};