返回

乘积最大子数组 - 动态规划的巧妙运用

前端

        

        

        

乘积最大子数组 - 动态规划的巧妙运用

在 LeetCode 的 HOT 100 系列文章中,我们今天将深入解析「乘积最大子数组」题目,带领你领略动态规划的巧妙运用。在本文中,我们将从问题的背景引入,逐步解析动态规划的递推公式,并结合具体示例进行详细讲解。最后,我们将总结出解决这类问题的通用思路,帮助你在未来的 LeetCode 征途中如虎添翼。

题目背景

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

动态规划算法解析

为了解决这个问题,我们可以使用动态规划算法。动态规划是一种解决复杂问题的一种方法,它将问题分解成一系列子问题,然后逐步解决这些子问题,最终得到整个问题的解。

在「乘积最大子数组」问题中,我们可以将子数组划分为两类:

  • 乘积为正数的子数组
  • 乘积为负数的子数组

对于乘积为正数的子数组,我们可以使用以下递推公式来计算其乘积最大值:

dp[i] = max(dp[i-1] * nums[i], nums[i])

其中,dp[i]表示以第i个元素结尾的乘积最大子数组的乘积。

对于乘积为负数的子数组,我们可以使用以下递推公式来计算其乘积最大值:

dp[i] = min(dp[i-1] * nums[i], nums[i])

其中,dp[i]表示以第i个元素结尾的乘积最小子数组的乘积。

示例

为了更好地理解动态规划的递推公式,我们来看一个具体的示例。

给定数组 nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4],我们按照动态规划的递推公式计算dp数组:

  • dp[0] = nums[0] = -2
  • dp[1] = max(dp[0] * nums[1], nums[1]) = max(-2 * 1, 1) = 1
  • dp[2] = max(dp[1] * nums[2], nums[2]) = max(1 * (-3), -3) = -3
  • dp[3] = max(dp[2] * nums[3], nums[3]) = max(-3 * 4, 4) = 4
  • dp[4] = max(dp[3] * nums[4], nums[4]) = max(4 * (-1), -1) = -4
  • dp[5] = max(dp[4] * nums[5], nums[5]) = max(-4 * 2, 2) = 2
  • dp[6] = max(dp[5] * nums[6], nums[6]) = max(2 * 1, 1) = 2
  • dp[7] = max(dp[6] * nums[7], nums[7]) = max(2 * (-5), -5) = -10
  • dp[8] = max(dp[7] * nums[8], nums[8]) = max(-10 * 4, 4) = 4

最终,dp数组的最大值为4。因此,乘积最大子数组为[4, -1, 2, 1],其乘积为8。

通用思路

在解决「乘积最大子数组」问题时,我们可以按照以下通用思路进行:

  1. 将子数组划分为两类:乘积为正数的子数组和乘积为负数的子数组。
  2. 对于乘积为正数的子数组,使用递推公式计算其乘积最大值。
  3. 对于乘积为负数的子数组,使用递推公式计算其乘积最小值。
  4. 比较所有子数组的乘积最大值,找到最大的一个。
  5. 找到乘积最大子数组,输出其乘积。

总结

「乘积最大子数组」问题是LeetCode HOT 100系列中的一道经典题目,通过动态规划的巧妙运用,我们可以高效地解决这个问题。在本文中,我们详细解析了动态规划的递推公式,并结合具体示例进行了详细讲解。同时,我们也总结出了解决这类问题的通用思路,希望对你的LeetCode征程有所帮助。