算法学习记录(七十二)

79 阅读1分钟

152. 乘积最大子数组

给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。

测试用例的答案是一个 32-位 整数。

子数组 是数组的连续子序列。

image.png

解: 子数组问题一般都是以第i个元素作为子数组结尾时的情况来进行分析。

这里分析以第i个元素作为子数组结尾时,它所能达到的最大乘积是多少。

可能性分析:

  • 只有第i个元素本身。 譬如:[10, -1, 1]
  • 第i-1个元素的最大乘积再乘以第i个元素。 譬如: [10, 1, 2]
  • 第i-i个元素的最小乘积再乘以第i个元素。 譬如: [10, -1, -2] 可以看出当前元素的结果依赖于上一个元素的结果。所以使用动态规划求解,再顺便用滚动数组的方式优化空间。
const maxProduct = function(nums) {
    if (!nums.length) return 0
    // 以上一个元素结尾时的最大乘积
    let preMax = nums[0]
    // 以上一个元素结尾时的最小乘积
    let preMin = nums[0]
    // 全局最大乘积
    let resMax = nums[0]
    for (let i = 1; i < nums.length; i++) {
        const p1 = nums[i]
        const p2 = preMax * nums[i]
        const p3 = preMin * nums[i]
        preMax = Math.max(p1, p2, p3)
        preMin = Math.min(p1, p2, p3)
        resMax = Math.max(preMax, resMax)
    }
    return resMax
};