连续子串的最大乘机

题目描述:

连续子串的最大乘机

解法一:动态规划

设dpMax[i]为当前找到的最大值,dpMin[i]为当前找到的最小值

求dpMax的方法:

nums[i]>0 dpMax[i-1]>0 则dpMax[i]=dpMax[i-1]*nums[i]

nums[i]>0 dpMax[i-1]<0 则dpMax[i]=nums[i]

nums[i]<0 dpMin[i-1]<0 则dpMax[i]=dpMin[i-1]*nums[i]

nums[i]<0 dpMin[i-1]>0 则dpMax[i]=nums[i]

求dpMin方法:

nums[i]>0 dpMin[i-1]>0 则dpMin[i]=nums[i]

nums[i]>0 dpMin[i-1]<0 则dpMin[i]=nums[i]*dpMin[i-1]

nums[i]<0 dpMax[i-1]>0 则dpMin[i]=dpMax[i-1]*nums[i]

nums[i]<0 dpMax[i-1]<0 则dpMin[i]=nums[i]

我们注意到,在求dpMax时,只用到了dpMax[i-1]*nums[i],dpMin[i-1]*nums[i],nums[i]

同理,在求dpMin时,只用到了nums[i]*dpMin[i-1],dpMax[i-1]*nums[i],nums[i]

因此我们只需找出dpMax[i-1]*nums[i],dpMin[i-1]*nums[i],nums[i]三者的最大值和最小值作为dpMax[i]、dpMin[i]。

此外在编写代码的时候我们发现,我们只用到dpMax[i-1]、dpMin[i-1]、dpMin[i]、dpMin[i]的信息,因此我们不需要用数组来保存,只需用dpMax和dpMin记录即可。

代码如下:

#include <math.h>

#include <iostream>

using namespace std;

class Solution {

public:

    int maxProduct(vector<int>& nums) {

        int len=nums.size();

        int dp=nums[0];

        int dn=nums[0];

        int temp=nums[0];

        for(int i=1;i<len;i++){

            int tempdn=dn;

            int tempdp=dp;

            dn=min(tempdp*nums[i],min(nums[i],tempdn*nums[i]));

            dp=max(tempdp*nums[i],max(nums[i],tempdn*nums[i]));

            //cout<<dn<<" "<<dp<<endl;

            if(dp>temp){

                temp=dp;

            }

        }

        return temp;

    }

};