给定一个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; } }