动态规划-连续子数组的最大乘积

一、问题描述

二、解题思路

最大最小值都是在下面三种情况产生:

1.当前元素        nums[i]

2.前一个最大乘积*当前元素              maxArr[i-1]*nums[i]  

3.前一个最小乘积*当前元素              minArr[i-1]*nums[i]

取最小值就是取三者中最小的,取最大值就是取三者中最大的

这里的最大最小值可以理解为:必须包含第i个元素时(相当于划定右侧范围),前i个元素子数组最大最小值

这里直接看不太好理解,举个例子来看一下:

nums        =            [3 , 2  -1  4]

maxArr:                   3   6   -1  4

minArr:                    3   2   -6  -24

初始情况下,maxArr[0]=3,minArr[0]=3;

当遇到nums[1]=2时,maxArr[1]=maxArr[0]*nums[1];

当遇到nums[2]=-1时,maxArr[2]=nums[2];minArr[2]=maxArr[1]*nums[2];

当遇到nums[3]=4时,maxArr[3]=nums[3];minArr[3]=minArr[2]*nums[3];

三、代码实现

import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int maxProduct (int[] nums) {
        int maxRes=nums[0];
        int len=nums.length;
        //设置两个数组,记录当前最大、最小乘积
        int[] maxArr=new int[len];
        int[] minArr=new int[len];
        //最大最小值都是在下面三种情况产生:
        //(1)当前元素、(2)前一个最大乘积*当前元素、(3)前一个最小乘积*当前元素
        for(int i=0;i<len;i++){
            if(i==0){
                maxArr[0]=nums[0];
                minArr[0]=nums[0];
            }else{
                maxArr[i]=Math.max(Math.max(nums[i],maxArr[i-1]*nums[i]),minArr[i-1]*nums[i]);
                minArr[i]=Math.min(Math.min(nums[i],maxArr[i-1]*nums[i]),minArr[i-1]*nums[i]);
                maxRes=Math.max(maxArr[i],maxRes);
            }
        }
        //比如是nums=[3,2,-1,4]
        //maxArr:   3   6   -1  4
        //minArr:   3   2   -6  -24

        return maxRes;
    }
}

四、刷题链接

连续子数组的最大乘积_牛客题霸_牛客网

### C语言实现连续子数组最大乘积算法 为了求解给定整数数组中的连续子数组最大乘积,可以采用动态规划的方法来解决这个问题。下面展示了一个完整的C语言程序示例: ```c #include <stdio.h> #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) int maxProduct(int* nums, int numsSize){ if (numsSize == 0) { return 0; } // 初始化当前最大最小值以及最终结果 int curMax = nums[0]; int curMin = nums[0]; int result = nums[0]; for (int i = 1; i < numsSize; ++i) { // 记录下一轮使用的curMax和curMin之前的状态 int temp = curMax; // 更新当前最大值与最小值 curMax = MAX(MAX(curMax * nums[i], curMin * nums[i]), nums[i]); curMin = MIN(MIN(temp * nums[i], curMin * nums[i]), nums[i]); // 更新全局最优解 result = MAX(result, curMax); } return result; } ``` 此代码实现了通过维护两个变量`curMax`和`curMin`分别记录到当前位置为止的最大累积乘积和最小累积乘积[^4]。这是因为当遇到负数时,之前的最小值可能会变成新的最大值。 #### 函数解释 - `MAX(a, b)` 和 `MIN(a, b)` 宏定义用于比较两个数值大小。 - 如果输入为空,则直接返回零作为特殊情况处理。 - 使用三个主要变量:`curMax`, `curMin` 来跟踪局部极值;还有一个变量 `result` 存储整个过程中发现的最佳答案。 - 遍历数组,在每一步都更新这三个变量直到结束。 上述方法不仅考虑到了正数的影响也兼顾了负数可能带来的反转效果,从而确保能够正确计算出任意情况下连续子数组最大乘积[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值