给你一个整数数组 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] <= 10nums的任何子数组的乘积都 保证 是一个 32-位 整数
求解
public int maxProduct(int[] nums) {
//连续的最大乘积子数组--重复子问题
//1.dp[i]定义为以元素i结尾的最大乘积
//2.状态转移:dp[i] = dp[i-1] * nums[i]//保证成绩>dp[i-1]
//3.dp[0] = nums[0]
//发现因为负数的存在,上述转移公式有问题,多了个状态,再加一维
//dp[i][0]为以i结尾最小值 dp[i][1]为以i结尾最大值
//如果nums[i]>=0 dp[i][0] = Math.min(nums[i], dp[i - 1][0] * nums[i]); dp[i][1] = Math.max(nums[i], dp[i - 1][1] * nums[i]);
//如果<0 dp[i][0]= Math.min(nums[i], dp[i - 1][1] * nums[i]); dp[i][1] = Math.max(nums[i], dp[i - 1][0] * nums[i]); 无论dp[i-1][j]是正还是负
//最后遍历dp取最大值即可
}
public class Solution {
public int maxProduct(int[] nums) {
int len = nums.length;
if (len == 0) {
return 0;
}
// 状态定义:以索引 i 结尾
int[][] dp = new int[len][2];
dp[0][0] = nums[0];
dp[0][1] = nums[0];
for (int i = 1; i < len; i++) {
if (nums[i] >= 0) {
dp[i][1] = Math.max(nums[i], dp[i - 1][1] * nums[i]);
dp[i][0] = Math.min(nums[i], dp[i - 1][0] * nums[i]);
} else {
dp[i][1] = Math.max(nums[i], dp[i - 1][0] * nums[i]);
dp[i][0] = Math.min(nums[i], dp[i - 1][1] * nums[i]);
}
}
int res = dp[0][1];
for (int i = 1; i < len; i++) {
res = Math.max(res, dp[i][1]);
}
return res;
}
}
作者:liweiwei1419
链接:https://leetcode.cn/problems/maximum-product-subarray/solutions/251440/dong-tai-gui-hua-li-jie-wu-hou-xiao-xing-by-liweiw/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
```