LeetCode 152. 乘积最大子数组
贪心 \(O(n)\)
对于某个序列中的某个元素nums[i]来说,设置j为其向前扫描的指针,可知随着j不断向前移动,nums[j~i]乘积的绝对值是不断增加的(除非是遇到0).因此我们只要寻找能够保证nums[j~i] > 0的最小的j就行。
具体的做法,则是在线性扫描的过程中,维护两个值f和g.f表示前num[1~i-1]中乘积的最大值(包括i-1,由于这个答案的形成过程中,每次迭代的时候,当前的元素一定参与乘积的运算,所以可以保证是连续的子数组乘积)g表示前nums[1~i-1]中乘积的最小值(负数,最小表示绝对值最大)。之后看当前nums[i]是大于0还是小于0,大于0那就乘f,乘积为fa,小于0那就乘g,乘积为ga。等于0,那也没办法,乘吧。实际编码我们可以从a, fa, ga中三者挑选最大最小值来维护f, g。
class Solution {
public:
int maxProduct(vector<int>& nums) {
int res = nums[0], f = nums[0], g = nums[0];
for (int i = 1; i < nums.size(); i ++)
{
int a = nums[i], fa = f * a, ga = g * a;
f = max(a, max(fa, ga));
g = min(a, min(fa, ga));
res = max(res, f);
}
return res;
}
};

浙公网安备 33010602011771号