乘积最大子数组
题目描述:
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
子数组 是数组的连续子序列。
思路:
动态规划,但是是找最大成绩,所以需要考虑正负情况,d[i]表示以第i个元素为最后一个元素的子数组的最大乘积,若nums[i]为正,应该是找Math.max(d[i-1]*nums[i],nums[i]),但是若nums[i]为负,d[i] 应该是nums[i]乘以以i-1结尾的子数组的成绩最小值,所以一个d[i]数组不够,需要同时维护dmax[i],与dmin[i].
代码:
//动态规划
public static int maxProduct1(int[] nums) {
int[] dmax = new int[nums.length];
int[] dmin = new int[nums.length];
dmax[0]=nums[0];
dmin[0]=nums[0];
int res = nums[0];
for (int i = 1; i < nums.length; i++) {
if(nums[i]>=0){
dmax[i] = Math.max(dmax[i-1]*nums[i],nums[i]);
dmin[i] = Math.min(dmin[i-1]*nums[i],nums[i]);
}else{
dmax[i] = Math.max(dmin[i-1]*nums[i],nums[i]);
dmin[i] = Math.min(dmax[i-1]*nums[i],nums[i]);
}
res = Math.max(res,dmax[i]);
}
return res;
}
//以0划分区间,而后判断负数奇偶,若为偶数个,直接返回所有数字乘积
//若为奇数个,要么舍弃最左边的负数,要么舍弃最右边的负数,分别计算一下然后返回较大值
public int maxProduct(int[] nums) {
int a=1;
int max=nums[0];
for(int num:nums){
a=a*num;
if(max<a)max=a;
if(num==0)a=1;
}
a=1;
for(int i=nums.length-1;i>=0;i--){
a=a*nums[i];
if(max<a)max=a;
if(nums[i]==0)a=1;
}
return max;
}