LeetCode 152. 乘积最大子数组

题目

给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。测试用例的答案是一个 32 位整数。子数组是数组的连续子序列。

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

方法一:暴力解法

计算每一种非空连续子数组的乘积取最大值

class Solution(object):
    def maxProduct(self, nums):
        dp = [[0] * len(nums) for row in range(len(nums))]
        sum = float('-INF')
        for i in range(len(nums)):
            for j in range(i, len(nums)):
                if i == j:
                    dp[i][j] = nums[i]
                else:
                    dp[i][j] = nums[j] * dp[i][j-1]
                sum = max(sum, dp[i][j])
        return sum

超出时间限制

方法二:动态规划

因为此数组为整数数组而非正整数数组,所以某个位置的最大乘积无法由以其前一个数结尾的连续子数组的最大乘积乘以当前位置的值得到。

  • dpMax[i] 记录以第 i 个元素结尾的连续子数组的最大乘积,dpMin[i] 记录以第 i 个元素结尾的连续子数组的最小乘积
  • 初始化 dpMax[0] 和 dpMin[0],若此时数组只有一个值,那么最大乘积和最小乘积为它本身
  • 循环遍历数组 nums
    • 记录 dpMax[i]
    • 记录 dpMin[i]
  • maximum 表示最大乘积
  • 循环数组 dpMax,更新最大乘积 maximum
class Solution(object):
    def maxProduct(self, nums):
        dpMax, dpMin = [0]*len(nums), [0]*len(nums)
        dpMax[0], dpMin[0] = nums[0], nums[0]
        for i in range(1, len(nums)):
            dpMax[i] = max(dpMax[i-1]*nums[i], dpMin[i-1]*nums[i], nums[i])
            dpMin[i] = min(dpMax[i-1]*nums[i], dpMin[i-1]*nums[i], nums[i])
        maximum = float('-INF')
        for i in range(len(dpMax)):
            maximum = max(maximum, dpMax[i])
        return maximum
参考

代码相关:https://leetcode.cn/problems/maximum-product-subarray/solution/cheng-ji-zui-da-zi-shu-zu-by-leetcode-solution/

你可能感兴趣的:(LeetCode 152. 乘积最大子数组)