68 lines
2.7 KiB
Java
68 lines
2.7 KiB
Java
package dynamic_programming;
|
||
/**
|
||
* 题目: 152. 乘积最大子数组 (MaxProduct)
|
||
* 描述:给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续 子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
|
||
* 测试用例的答案是一个 32-位 整数。
|
||
|
||
* 示例 1:
|
||
输入: nums = [2,3,-2,4]
|
||
输出: 6
|
||
解释: 子数组 [2,3] 有最大乘积 6。
|
||
|
||
* 链接:https://leetcode.cn/problems/maximum-product-subarray/
|
||
*/
|
||
//不会
|
||
//二刷不会
|
||
public class MaxProduct {
|
||
|
||
/**
|
||
* 用动态规划维护遍历到当前位置时,以 nums[i] 结尾的「最大乘积」和「最小乘积」:
|
||
* - prevMax:前一步的最大乘积
|
||
* - prevMin:前一步的最小乘积(因为负数相乘会翻转大小)
|
||
* 对于新元素 x = nums[i],候选值只有三种:
|
||
* 1. 单独以 x 为一段子数组
|
||
* 2. 将 x 与 prevMax 相乘(延续最大乘积序列)
|
||
* 3. 将 x 与 prevMin 相乘(延续最小乘积序列,有可能翻转成最大)
|
||
* 因此通过 max(x, x*prevMax, x*prevMin) 得到新的 currMax,
|
||
* 同理用 min(x, x*prevMax, x*prevMin) 得到 currMin。
|
||
* 然后更新全局答案 ans = max(ans, currMax)。
|
||
*/
|
||
public int maxProduct(int[] nums) {
|
||
if (nums == null || nums.length == 0) {
|
||
throw new IllegalArgumentException("数组不能为空");
|
||
}
|
||
|
||
// 初始化:第 0 个位置的最大/最小乘积都等于 nums[0]
|
||
int prevMax = nums[0];
|
||
int prevMin = nums[0];
|
||
int ans = nums[0];
|
||
|
||
// 从 i=1 开始遍历
|
||
for (int i = 1; i < nums.length; i++) {
|
||
int x = nums[i];
|
||
// 三个候选值:x、x*prevMax、x*prevMin
|
||
int candidateMax = Math.max(x, Math.max(x * prevMax, x * prevMin));
|
||
int candidateMin = Math.min(x, Math.min(x * prevMax, x * prevMin));
|
||
|
||
// 更新当前的最大/最小乘积
|
||
prevMax = candidateMax;
|
||
prevMin = candidateMin;
|
||
|
||
// 更新全局答案
|
||
ans = Math.max(ans, prevMax);
|
||
}
|
||
|
||
return ans;
|
||
}
|
||
|
||
// 简单测试
|
||
public static void main(String[] args) {
|
||
MaxProduct sol = new MaxProduct();
|
||
System.out.println(sol.maxProduct(new int[]{2, 3, -2, 4})); // 输出 6
|
||
System.out.println(sol.maxProduct(new int[]{-2, 0, -1})); // 输出 0
|
||
System.out.println(sol.maxProduct(new int[]{-2, 3, -4})); // 输出 24
|
||
System.out.println(sol.maxProduct(new int[]{-1, -3, -10, 0, 60})); // 输出 60
|
||
System.out.println(sol.maxProduct(new int[]{-2, -5, -2, -4, 3})); // 输出 240
|
||
}
|
||
}
|