给定一个double类型的数组arr,其中的元素可正可负可0,返回连续子数组累乘的最大乘积。
数据范围:数组大小满足
,数组中元素满足
进阶:空间复杂度
,时间复杂度
[-2.5,4,0,3,0.5,8,-1]
12.00000
取连续子数组[3,0.5,8]可得累乘的最大乘积为12.00000
[1.0,0.0,0.0]
1.00000
取连续子数组[1.0]可得累乘的最大乘积为1.00000
public class Solution {
public double maxProduct(double[] arr) {
double max = 0.0 ;
double dp[][] = new double[arr.length][arr.length]; //为了存放最大值
if(arr.length == 1){
return arr[0];
}
int j = 0;
for(int i = 0 ; i < arr.length; i ++){
dp[i][i] = arr[i];
double sum = arr[i];//为了进行累乘
for(j = i + 1 ; j < arr.length; j ++){
if(arr[j] == 0){
dp[i][j] = Math.max(dp[i][j - 1],0);
j = j + 1;//这里是因为,如果不多加一次,那么直接跳出循环,就会到
//22行,此时22行减 了1.
break;
}
sum = sum * arr[j];
dp[i][j] = Math.max(dp[i][j - 1],sum);
}
max = Math.max(max,dp[i][j - 1]);//由于考虑到如果是全部不为0的情况下,那么j一定会多加1,
//所以减掉1
}
return max;
}
} public class Solution {
public double maxProduct(double[] arr) {
double[] mx = new double[arr.length];
double[] mi = new double[arr.length];
mx[0] = arr[0];
mi[0] = arr[0];
double res = arr[0];
for (int i = 1; i < arr.length; i++) {
mx[i] = Double.max(arr[i], Double.max(mi[i - 1] * arr[i], mx[i - 1] * arr[i]));
mi[i] = Double.min(arr[i], Double.min(mi[i - 1] * arr[i], mx[i - 1] * arr[i]));
if (res < mx[i])
res = mx[i];
}
return res;
}
} public class Solution {
public double maxProduct(double[] arr) {
int n = arr.length;
double mi[] = new double[n + 1];
double ma[] = new double[n + 1];
ma[0] = 1;
mi[0] = 1;
double res = -10101;
for(int i = 1;i <= n;i++){
ma[i] = Math.max(arr[i - 1],arr[i - 1] * ma[i - 1]);
ma[i] = Math.max(ma[i],arr[i - 1] * mi[i - 1]);
mi[i] = Math.min(arr[i - 1],mi[i - 1] * arr[i - 1]);
mi[i] = Math.min(mi[i],arr[i - 1] * ma[i - 1]);
res = Math.max(ma[i],res);
}
return res;
}
} public class Solution {
public double maxProduct(double[] arr) {
int n = arr.length;
//保存最大和最小。动态规划;maxtmp[i]表示以节点i为结尾的连续子数组的最大乘机
double[] maxtmp=new double[n];
double[] mintmp=new double[n];
maxtmp[0] = arr[0];
mintmp[0] = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] > 0) {
maxtmp[i] = Math.max(arr[i], arr[i] * maxtmp[i-1]);
mintmp[i] = Math.min(arr[i], arr[i] * mintmp[i-1]);
} else {
maxtmp[i] = Math.max(arr[i], arr[i] * mintmp[i-1]);
mintmp[i] = Math.min(arr[i], arr[i] * maxtmp[i-1]);
}
}
//找出以每个节点为结尾的最大值中的最大值
double ans=maxtmp[0];
for(int i=1;i<n;i++){
ans=maxtmp[i]>ans?maxtmp[i]:ans;
}
return ans;
}
} public class Solution {
//连续子数组乘积的最大值
public double maxProduct(double[] arr) {
double min=arr[0];
double max=arr[0];
double res=arr[0];
//最大值有可能出现在之前的最小值*当前值,比如最小值为-100,arr[i]<0,同理,最小值也可能出现在之前的最大值,所以每次比较三个值
for(int i=1;i<arr.length;i++){
double last_max=max,last_min=min;
min=Math.min(arr[i],Math.min(arr[i]*last_min,arr[i]*last_max));
max=Math.max(arr[i],Math.max(arr[i]*last_min,arr[i]*last_max));
res=Math.max(max,res);
}
return res;
}
} public class Solution {
public double maxProduct(double[] arr) {
int n = arr.length;
double res = arr[0], max = arr[0], min = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] > 0) {
max = Math.max(arr[i], arr[i] * max);
min = Math.min(arr[i], arr[i] * min);
} else {
double pre = max;
max = Math.max(arr[i], arr[i] * min);
min = Math.min(arr[i], arr[i] * pre);
}
res = Math.max(res, max);
}
return res;
}
}