给你一个整数数组
nums,请你找出数组中乘积最大的非空连续 子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。测试用例的答案是一个 32-位 整数。
解法1 暴力解法
思路
最简单的方法就是去连乘,既然是子数组,那么肯定是连续的,两层循环一直找到最大值即可。但是要注意可以是一个子数组。暴力解法可以AC。
代码
function maxProduct(nums: number[]): number {
let result = nums[0];
for (let i = 0; i < nums.length; i++) {
let temp = nums[i];
for (let j = i + 1; j < nums.length; j++) {
temp *= nums[j];
result = Math.max(result, temp, nums[j]);
}
}
return result;
};
时空复杂度
时间复杂度:O(n^2)
空间复杂度:O(1)
解法2 动态规划
思路
如果用动态规划去寻找乘积最大子数组不能简单用“前缀积”来处理,因为如果遇到负数,负数 * 负数 = 正数,所以我们不能只维护最大乘积,还要同时记录最小乘积。
maxSoFar:以 i 结尾的子数组的最大乘积
minSoFar:以 i 结尾的子数组的最小乘积(因为可能为负数)
代码
function maxProduct(nums: number[]): number {
let result = nums[0];
let maxSoFar = nums[0];
let minSoFar = nums[0];
for (let i = 1; i < nums.length; i++) {
const cur = nums[i];
const candidates = [cur, cur * maxSoFar, cur * minSoFar];
const newMax = Math.max(...candidates);
const newMin = Math.min(...candidates);
maxSoFar = newMax;
minSoFar = newMin;
result = Math.max(result, maxSoFar);
}
return result;
};
时空复杂度
时间复杂度:O(n)
空间复杂度:O(1)