Leetcode 152.乘积最大子数组

124 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情

1.题目

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

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

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

2.思路

这道题需要找到最大乘积的非空连续子数组, 我们可以考虑使用滑动窗口的方法,便利数组进行累乘,不停的向右扩展,然后保持一个变量用以保存当前最大乘积,每次向右累乘时同时与当前最大乘积比较并更新,只是需要考虑乘积等于0或者小于0的情况,在等于0的时候需要重置,而在小于0的时候将最大值置换。

然后我们除了这个滑动窗口思路以外还可以采用动态规划的方法,和滑动窗口方法差不太多我们将最大乘积子数组分解成前一位最大值乘以当前值,分解这个方程,然后从初始位置开始计算。

我们同样通过遍历数组来乘积,不过我们保存两个变量一个最大值一个最小值,在遇到负值时将最大值与最小值进行交换以保证后续再遇到负数时乘积为最大。使用一个dp数组来保存每一个位置的最大乘积,最后将数组中的每个位置的乘积进行比较返回最大值。

3.代码

/**

  • @param {number[]} nums

  • @return {number} */ var maxProduct = function(nums) { let max = min = nums[0], dp = [nums[0]]

    for (let i=1; i<nums.length; i++) { if (nums[i] < 0) { [max, min] = [min, max] }

     max = Math.max(max*nums[i], nums[i])
     min = Math.min(min*nums[i], nums[i])
    
     dp[i] = max
    

    }

    return Math.max(...dp) };