//给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
//
//
//
// 示例 1:
//
// 输入: [2,3,-2,4]
//输出: 6
//解释: 子数组 [2,3] 有最大乘积 6。
//
//
// 示例 2:
//
// 输入: [-2,0,-1]
//输出: 0
//解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
// Related Topics 数组 动态规划
// 👍 1119 👎 0
先按简单的写法来实现,时间复杂度为O(n!)
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int maxProduct(int[] nums) {
int len = nums.length;
//代表从i到j相乘的积
int[] arr = new int[len];
int max = nums[0];
for(int i = 0;i<len;i++){
for(int j = i;j<len;j++){
if(j == i){
arr[j] = nums[j];
}else {
arr[j] = arr[j - 1] * nums[j];
}
if(arr[j]>max){
max = arr[j];
}
}
}
return max;
}
}
//leetcode submit region end(Prohibit modification and deletion)
再来一个使用DP的写法
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int maxProduct(int[] nums) {
int len = nums.length;
//假设从i到j相乘的积为最大值,按nums[j]是否大于0分两种情况
//如果大于0,则i到j-1积最大;如果小于0,则i到j-1积最小
int max = nums[0],min = nums[0],result = nums[0];
for(int i = 1;i<len;i++){
int m = max,n = min;
max = Math.max(m*nums[i],Math.max(nums[i],n*nums[i]));
min = Math.min(n*nums[i],Math.min(nums[i],m*nums[i]));
result = Math.max(max,result);
}
return result;
}
}
//leetcode submit region end(Prohibit modification and deletion)
其中max = Math.max(m*nums[i],Math.max(nums[i],n*nums[i]));这句可以这么理解,如果nums[i]大于0,则最大乘积可能是max*nums[i],此时max大于0。如果nums[i]小于0,则有可能是min*nums[i],此时min小于0。特殊的情况是max小于0,nums[i]大于0,则最大乘积是nums[i]。