88.乘积最大子数组
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续 子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
示例1:
输入: nums = [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例2:
输入: nums = [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
提示:
- 1 <= nums.length <= 2 * 104
- -10 <= nums[i] <= 10
- nums 的任何子数组的乘积都 保证 是一个 32-位 整数
代码:
class Solution {
public int maxProduct(int[] nums) {
//n为nums数组的长度
int n = nums.length;
//MaxF[i] 表示以 nums[i] 结尾的子数组的最大乘积
int[] MaxF = new int[n];
//MinF[i] 表示以 nums[i] 结尾的子数组的最小乘积(用于处理负数情况)
int[] MinF = new int[n];
//初始状态:第一个元素的最大和最小乘积就是它本身
MaxF[0] = nums[0];
MinF[0] = nums[0];
for(int i = 1;i<n;i++){
//先初始化为当前数字(相当于子数组只包含 nums[i])
MaxF[i] = nums[i];
MinF[i] = nums[i];
//状态转移:
//1.如果 nums[i] 是正数,MaxF[i] 可能是 MaxF[i-1] * nums[i](正数乘正数更大)
//2.如果 nums[i] 是负数,MaxF[i] 可能是 MinF[i-1] * nums[i](负数乘负数变正数)
//3.也可能直接取 nums[i](比如前面乘积是 0,nums[i] 是正数)
MaxF[i] = Math.max(Math.max(MinF[i-1]*nums[i],MaxF[i]),MaxF[i-1]*nums[i]);
// 同理,MinF[i] 可能是:
// 1. MaxF[i-1] * nums[i](正数乘负数变小)
// 2. MinF[i-1] * nums[i](负数乘负数变大,但这里取最小)
// 3. 直接取 nums[i](比如前面乘积是 0,nums[i] 是负数)
MinF[i] = Math.min(Math.min(MaxF[i-1]*nums[i],MinF[i]),MinF[i-1]*nums[i]);
}
//初始化为一个极小值
int res = -0x3f3f3f3f;
//遍历 MaxF 数组,找出全局最大值
for(int i = 0;i<n;i++)res = Math.max(res,MaxF[i]);
//返回最大乘积
return res;
}
}

浙公网安备 33010602011771号