1、题目描述
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
子数组 是数组的连续子序列。
2、算法分析
求数组中子区间的最大乘积,对于乘法,我们需要注意,负数乘以负数,会变成正数,所以解这题的时候我们需要维护两个变量,当前的最大值,以及最小值,最小值可能为负数,但没准下一步乘以一个负数,当前的最大值就变成最小值,而最小值则变成最大值了。
maxDP[i + 1] = max(maxDP[i] * A[i + 1], A[i + 1],minDP[i] * A[i + 1]) minDP[i + 1] = min(minDP[i] * A[i + 1], A[i + 1],maxDP[i] * A[i + 1]) dp[i + 1] = max(dp[i], maxDP[i + 1])
3、代码实现
/*
这个题有正数有负数,当正数*负数的时候,为负数
*/
class Solution {
public int maxProduct(int[] nums) {
// 判空数组
if(nums == null || nums.length == 0){
return 0;
}
// 定义结果集
int result = nums[0];
// 定义两个dp数组是以i为结尾的数组元素乘积的最大值和最小值
int[] maxDP = new int[nums.length];
int[] minDP = new int[nums.length];
// 初始化
maxDP[0] = nums[0];
minDP[0] = nums[0];
// 遍历
for(int i = 1;i < nums.length;i++){
// 最大值可能是 元素i本身,也可能是最大积与nums[i]相乘,最小积元素与nums[i]相乘
maxDP[i] = Math.max(nums[i],Math.max(maxDP[i - 1] * nums[i],minDP[i - 1]* nums[i]));
minDP[i] = Math.min(nums[i],Math.min(maxDP[i - 1] * nums[i],minDP[i - 1]* nums[i]));
result = Math.max(result,maxDP[i]);
}
return result;
}
}