1. 题目
读题
https://leetcode.cn/problems/maximum-product-subarray/
考查点
2. 解法
思路
思路是这样的:我们要找到一个子数组,使得它的乘积最大。我们可以用动态规划的方法,定义一个状态dp[i],表示以第i个元素结尾的子数组的最大乘积。那么我们要求的就是dp[0]到dp[n-1]中的最大值,其中n是数组的长度。但是这样定义状态有一个问题,就是如果第i个元素是负数,那么它可能会把之前的最大乘积变成最小乘积,或者把之前的最小乘积变成最大乘积。所以我们需要同时维护两个状态,一个是max[i],表示以第i个元素结尾的子数组的最大乘积,另一个是min[i],表示以第i个元素结尾的子数组的最小乘积。那么我们要求的就是max[0]到max[n-1]中的最大值。那么如何更新这两个状态呢?我们可以根据第i个元素的正负号来分情况讨论:
- 如果第i个元素是正数,那么它会使得之前的最大乘积变得更大,也会使得之前的最小乘积变得更小。所以我们有:
- max[i] = max(nums[i], max[i-1] * nums[i])
- min[i] = min(nums[i], min[i-1] * nums[i])
- 如果第i个元素是负数,那么它会使得之前的最大乘积变成最小乘积,也会使得之前的最小乘积变成最大乘积。所以我们有:
- max[i] = max(nums[i], min[i-1] * nums[i])
- min[i] = min(nums[i], max[i-1] * nums[i])
- 如果第i个元素是0,那么它会使得之前的任何乘积都变成0。所以我们有:
- max[i] = 0
- min[i] = 0
由于每个状态只和前一个状态有关,所以我们可以用两个变量来代替数组,节省空间。另外,由于负数会导致最大和最小乘积交换,所以我们在更新之前要先判断当前元素的正负号,并且如果是负数就交换两个变量的值。
代码逻辑
- 步骤一:判断数组是否为空或者长度为0,如果是,就返回0,因为没有子数组。
- 步骤二:初始化两个变量max和min,分别表示以第一个元素结尾的子数组的最大乘积和最小乘积,也就是第一个元素本身。同时,初始化一个全局变量result,表示最终要返回的最大乘积,也就是max的初始值。
- 步骤三:从第二个元素开始遍历数组,对于每个元素,执行以下的子步骤:
- 子步骤一:判断当前元素的正负号,如果是负数,就交换max和min的值,因为负数会导致最大和最小乘积反转。
- 子步骤二:更新max和min的值,根据之前的思路,用当前元素和当前元素乘以之前的max或min来比较,取较大或较小的值作为新的max或min。
- 子步骤三:更新result的值,用当前的max和之前的result来比较,取较大的值作为新的result。
- 步骤四:遍历结束后,返回result作为答案。
具体实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class Solution { public int maxProduct( int [] nums) { // edge case if (nums == null || nums.length == 0 ) return 0 ; // initialize two variables to store the max and min product ending with current element int max = nums[ 0 ]; int min = nums[ 0 ]; // initialize a global variable to store the max product int result = max; // loop through the array for ( int i = 1 ; i < nums.length; i++) { // if current element is negative, swap max and min if (nums[i] < 0 ) { int temp = max; max = min; min = temp; } // update max and min max = Math.max(nums[i], max * nums[i]); min = Math.min(nums[i], min * nums[i]); // update result result = Math.max(result, max); } return result; } } |
3. 总结
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2019-05-01 java中的12种锁
2019-05-01 公平锁与非公平锁
2019-05-01 设计模式:门面模式(Facade)
2019-05-01 设计模式:装饰者模式
2019-05-01 设计模式:组合模式
2019-05-01 设计模式:桥接模式
2019-05-01 设计模式:适配器模式(Adapter)