问题描述
给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
测试用例的答案是一个 32-位 整数。
子数组 是数组的连续子序列。(连续子序列问题:就是序号是相互连着的:如 1、2、3、4)连续
(区分):元素连续以及相应的元素可删除,保证局部顺序有序的区别。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-product-subarray
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
第一联想到:53 最大子序和问题 (问题的描述相同,但是一个是乘积,一个是加合)
对于最大子序和问题,解法有两种:
一类是通过贪心的思路实现相应的输出。判断前一个值对下一个值的共享程度。
二:使用动态规划去记录下到子序列每一个结尾的和的情况。最后去探究最优解的值(寻找最大值)。最优解是:以第i个数结尾的子序列的和的最大情况
状态转移方程:dp[i] = Math.max(dp[i-1]+num[i],num[i])
借着该思路出发,进行同类迁移:使用动态规划的角度出发
使用乘法:还需要额外考虑一个点:符号问题 因此就需要考虑维护的是最大值以及最小值的问题。因为符号不同,就可以导致情况出现反转的现象。
具体代码的实现
class Solution {
public int maxProduct(int[] nums) {
// 子数组问题;动态规划实现(连续的子数组)
int maxValue [] = new int [nums.length];
int minValue [] = new int [nums.length];
int dp[] = new int [nums.length];
//dp[i] 表示以数组的第i 个数结尾的连续的子数组的最大乘积问题
//初始化:每个结尾都可以考虑以本身为单个的值
maxValue[0] = nums[0];
minValue[0] = nums[0];
int sum = 0;
//遍历 (for 循环实现)
for(int i = 1;i<nums.length;i++){
// 值问题的选择上进行区分:不再是单纯的本身的值
maxValue[i] =Math.max(nums[i]* maxValue[i-1],Math.max(nums[i],nums[i]*minValue[i-1]));
minValue[i] =Math.min(nums[i]* maxValue[i-1],Math.min(nums[i],nums[i]*minValue[i-1]));
}
//从新遍历一遍;获取相应的最值
int result = Integer.MIN_VALUE;
for(int i = 0;i<nums.length;i++){
result = Math.max(result,maxValue[i]);
}
return result;
}
}
对于情况的分类:不需要去考虑符合,而是去考虑他最值的情况:如当前的数为正数,则当前值* 前一个数的最大情况既可以满足。若当前值为负数,则当前值* 前一个数的最负数的情况(最小值)既可以满足。若为0的话,则就是其本身。
同理:维护相应的最小值的情况。
思路二(基于上面的结论的演进)
上述的算法实质上等同于维护了一个一维数组,用于保存其最大以及最小值,因此思考:是否有方法,能够对相应的空间压缩。因此联想到动态规划所学到的“滚动数组”。其思想就是将数组维护的最大值变成维护单个最值的问题。
carl哥:代码随想录中对滚动数组的描述
滚动数组:上一个数的最值都是用来维护和使用下一个的 ,
class Solution {
public int maxProduct(int[] nums) {
int maxValue = nums[0],minValue = nums[0],result = nums[0];
for(int i = 1;i<nums.length;i++){
int max = maxValue,min = minValue;
maxValue = Math.max(Math.max(nums[i]*max,nums[i]*min),nums[i]);
minValue = Math.min(Math.min(nums[i]*max,nums[i]*min),nums[i]);
result = Math.max(result,maxValue);
}
return result;
}
}
本文介绍了如何利用动态规划解决LeetCode上的最大乘积子数组问题,包括两种解法:标准DP和滚动数组优化。通过实例展示了如何考虑符号影响,以及如何通过滚动数组减少空间复杂度。
753

被折叠的 条评论
为什么被折叠?



