题目
给定一个整数数组
nums
,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。示例 1:
输入: [2,3,-2,4] 输出:6 解释: 子数组 [2,3] 有最大乘积 6。示例 2:
输入: [-2,0,-1] 输出: 0 解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
分析
方法一 暴力求解
求出所有连续子串的乘积,记录最大数字。虽然有些暴力但是还是可以通过。
时间复杂度on^2。
方法二
用三个变量,max curmax curmin 分别来 保存 最大乘积, 当前最大乘积, 当前最小乘积。
大概思路是这样的:遍历序列,每到一个位置都更新当前的最大乘积和最小成绩,更新最大乘积,即求出当前最优解。
计算最小乘积的意义在于,因为数字有正有负,所以最小乘积在乘上一个负数之后,就很有可能会变成一个最大乘积。
curmax = Max( nums[i], curmax*nums[i], curmin*nums[i])
curmin = Min ( nums[i], curmax*nums[i], curmin*nums[i])
max = Max( max , curmax)
时间复杂度On
代码
// 方法一
class Solution {
public int maxProduct(int[] nums) {
int len = nums.length;
if (len == 1) return nums[0];
int max = Integer.MIN_VALUE;
int[] dp = new int[len];
for (int i = 0; i < len; i++) {
dp[i] = nums[i];
max = Math.max(max,nums[i]);
}
for (int i = 1; i < len; i++) {
for (int j = 0; j+i < len && j < len; j++) {
dp[j] = dp[j]*nums[j+i];
max = Math.max(max,dp[j]);
}
}
return max;
}
}
//方法二
class Solution {
public int maxProduct(int[] nums) {
int max = nums[0];
int curmax = nums[0];
int curmin = nums[0];
for (int i = 1; i < nums.length; i++) {
int nextmax = nums[i] * curmax;
int nextmin = nums[i] * curmin;
curmax = max(nums[i], nextmax, nextmin);
curmin = min(nums[i], nextmax, nextmin);
max = Math.max(max,curmax);
}
return max;
}
public static int max(int a , int b , int c){
return Math.max(a,Math.max(b,c));
}
public static int min(int a, int b, int c){
return Math.min(a,Math.min(b,c));
}
}