[leetcode]152. Maximum Product Subarray 最大子序列乘积

题目:

Find the contiguous subarray within an array (containing at least one number) which has the largest product.

For example, given the array [2,3,-2,4],
the contiguous subarray [2,3] has the largest product = 6.

思路:

动态规划。

这道题类似于求最大子序列和。在求最大子序列和时,会比较当前值与当前值加上前面子序列的和,保留较大的一个。而在求最大乘积时,由于0和负数的存在,不能只考虑保留乘积最大的部分,还要考虑保留乘积最小的部分。

代码为:

int maxProduct(vector& nums) {
        if(nums.size()==1)
            return nums[0];
        int n=nums.size();
        vector maxPro(n,0),minPro(n,0);
        maxPro[0]=nums[0];
        minPro[0]=nums[0];
        int res=nums[0];
        for(int i=1;i

另外一个思路是我自己在做题时想的,比上文提到的思路繁琐,但时间复杂度也为O(n),先记录如下:

思路:

首先把0作为一个分界点,遇到0时,先找到前面序列的最大子序列乘积,在接下来的过程中,前面的子序列不在考虑。

在其中一段子序列中,记录下负数的个数,子序列的乘积tmpPro,从子序列开始到第一个负数的乘积subPro1和从最后一个负数到子序列最后的乘积subPro2,具体例子如下:

序列 -2,3,4,-3,3,1,-5,3

这里tmpPro=-3240,subPro1=-2,subPro2=-5*3=-15。由于负数个数为奇数,就有可能出现第一个负数为分界点和最后一个负数为分界点的情况,这里就需要比较tmpPro/subPro1和tmpPro/subPro2,选择其中最大的子序列乘积。同时这里也需要注意:

1)序列中有0,0等类似的情况,这时tmpPro=1,不能作为子序列的乘积,在这里加入tmpValid标记变量tmpPro是否可用

2)子序列中只有一个负数的情况,如-2,用上面的方法就会出现除数为1的情况,在这里加入subValid标记变量subPro1是否可除

代码:

在这段代码中,可以现在nums后插入0,这样就不用在最后又重复一段代码。

int maxProduct(vector& nums) {
        if(nums.size()==1)
            return nums[0];
        
        int maxPro=nums[0];
        int negNum=0;
        int tmpPro=1;
        int subPro1=1;
        int subPro2=1;
        bool tmpValid=0;
        bool subValid=0;
        for(int i=0;i


你可能感兴趣的:(leetcode)