跳至主要內容

152. 乘积最大子数组


152. 乘积最大子数组open in new window

🟠   🔖  数组 动态规划  🔗 力扣open in new window LeetCodeopen in new window

题目

Given an integer array nums, find a subarray that has the largest product, and return the product.

The test cases are generated so that the answer will fit in a 32-bit integer.

Example 1:

Input: nums = [2,3,-2,4]

Output: 6

Explanation: [2,3] has the largest product 6.

Example 2:

Input: nums = [-2,0,-1]

Output: 0

Explanation: The result cannot be 2, because [-2,-1] is not a subarray.

Constraints:

  • 1 <= nums.length <= 2 * 10^4
  • -10 <= nums[i] <= 10
  • The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer.

题目大意

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

解题思路

  • 给出一个数组,要求找出这个数组中连续元素乘积最大的值。
  • 分情况讨论:
    • 不和别人乘,就是 n 自己
    • n 是负数,乘上前面的最小积
    • n 是正数,乘上前面的最大积
  • 这一题是 DP 的题,状态转移方程是:最大值是 Max(f(n)) = Max( Max(f(n-1)) * n, Min(f(n-1)) * n, n);最小值是 Min(f(n)) = Min( Max(f(n-1)) * n, Min(f(n-1)) * n, n)。只要动态维护这两个值,如果最后一个数是负数,最大值就在负数 _ 最小值和自己中产生,如果最后一个数是正数,最大值就在正数 _ 最大值和自己中产生。

代码

function maxProduct(arr) {
	let res = arr[0];
	let max = arr[0];
	let min = arr[0];
	let temp1, temp2;
	for (let i = 1; i < arr.length; i++) {
		// 先计算好,免得下面重复计算两次,结果会出错
		temp1 = max * arr[i];
		temp2 = min * arr[i];

		max = Math.max(temp1, temp2, arr[i]);
		min = Math.min(temp1, temp2, arr[i]);
		res = Math.max(res, max);
	}
	return res;
}

相关题目

题号标题题解标签难度
53最大子数组和open in new window[✓]数组 分治 动态规划
198打家劫舍open in new window[✓]数组 动态规划
238除自身以外数组的乘积open in new window[✓]数组 前缀和
628三个数的最大乘积open in new window数组 数学 排序
713乘积小于 K 的子数组open in new window数组 二分查找 前缀和 1+