leetcode 152. Maximum Product Subarray (最大乘积子数组)

本文探讨了寻找数组中连续子数组的最大乘积问题,介绍了一种动态规划方法,通过记录最大值和最小值来解决负数带来的复杂性,确保能够正确处理所有情况,实现高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has the largest product.

Example 1:

Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.

给出一个数组,让找出连续的子数组使乘积最大,子数组必须是连续的

思路:
如果是连续子数组求和,遇到负数可以跳过,但是乘积有一个问题,就是负负得正,可能最小的负数和一个负数相乘就变成了最大积。
所以要同时记录下最小值,最大值,以便得到和当前元素相乘后得到的最大乘积。
结果的最大乘积不能直接取最后一个的最大值,要取全局最大值。
可以用DP数组记录下最小值最大值

class Solution {
public:
    int maxProduct(vector<int>& nums) {
        vector<int> max_current(nums.size(), 0);
        vector<int> min_current(nums.size(), 0);

        int max_product = nums[0];
        
        max_current[0] = nums[0];
        min_current[0] = nums[0];
        
        for (int i = 1; i < nums.size(); i++) {
            int cur_max = nums[i] * max_current[i - 1];
            int cur_min = nums[i] * min_current[i - 1];
            max_current[i] = max(nums[i], max(cur_max, cur_min));
            min_current[i] = min(nums[i], min(cur_max, cur_min));
                                 
            max_product = max(max_current[i], max_product);
        }
        
        return max_product;
    }
};

因为最小值,最大值每次只和前一个的值相关,所以只需要一个变量来保存

    public int maxProduct(int[] nums) {
        if(nums == null || nums.length == 0) {
            return 0;
        }
        
        int n = nums.length;
        int curMin = nums[0];
        int curMax = nums[0];
        int result = nums[0];
        
        for(int i = 1; i < nums.length; i++) {            
            int localMin = curMin*nums[i]; //避免后面重复计算
            int localMax = curMax*nums[i]; //避免后面重复计算          
            curMin = Math.min(Math.min(localMin, localMax), nums[i]);
            curMax = Math.max(Math.max(localMin, localMax), nums[i]);
            result = Math.max(result, curMax);
        }
        
        return result;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值