[leetcode]152.乘积最大子数组

给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字)。

示例 1:

输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。

示例 2:

输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。

思路:
动态规划:
类似于最大子序列和的思想,不过本题说的是最大子数组,即中间必须要连续,而且存在负数,由于负负得正,即如果遍历到i的时候dp[i]保存当前的最大值,若nums[i]<0则dp[i]*nums[i+1]为最小值,同理,若dp[i]保存遍历到i的最小值,nums[i+1]为负,则dp[i]*nums[i+1]为最大值,所以本题需要两个dp数组,分别保存到当前的最大值与最小值
状态转移方程:

maxDP[i+1]=max(maxDP[i]*nums[i+1],nums[i+1],maxDp[i]*A[i+1])
minDP[i+1]=min(minDP[i]*nums[i+1],nums[i+1],minDp[i]*A[i+1])

初始maxDP[0]=minDP[0]=nums[0].
最后返回maxDP[nums.size()-1]即可。
优化:不使用dp数组,可以直接用两个整型变量保存当前最大值与最小值,遍历到最后输出最大值即可。

AC代码:(C++)

class Solution {
   public:
    int maxProduct(vector<int>& nums) {
        int size = nums.size();
        if (size == 0)
            return 0;
        else if (size == 1)
            return nums[0];
        int maxP = nums[0], minP = nums[0], ans = nums[0];
        for (int i = 1; i < size; i++) {
            int temp = maxP;
            maxP = max(max(maxP * nums[i], nums[i]), minP * nums[i]);
            minP = min(min(temp * nums[i], nums[i]), minP * nums[i]);
            ans = max(maxP, ans);
        }
        return ans;
    }
};

你可能感兴趣的:(LeetCode)