给定一个整数数组 nums
,表示一个班级中所有学生在一次考试中的成绩。老师想从这个班级中选出一部分同学组成一个非空小组,使得这个小组的实力值最大。小组的实力值定义为小组中所有学生成绩的乘积。请返回老师创建的小组能得到的最大实力值。
这个问题可以通过动态规划的思想来解决。我们需要维护两个变量,mn
和 mx
,分别表示当前遍历到的元素之前可能的最小乘积和最大乘积。对于数组中的每个元素,我们考虑两种情况:不包括当前元素和包括当前元素。对于每种情况,我们分别更新 mn
和 mx
。
mn
和 mx
保持不变。由于数组中可能包含负数,我们需要特别注意负数的乘积可能会变成正数,这可能会影响最终的最大乘积。
输入: nums = [3, -1, -5, 2, 5, -9]
输出: 1350
mn = 3
(数组的第一个元素)mx = 3
(同上)mn
和 mx
-1
-5
2
5
-9
最终,mx
的值为 1350
,这是所有可能子集中的最大乘积。
通过这个详细的步骤,我们可以看到每次迭代是如何考虑当前元素 x
是否加入到子集中,以及如何影响最小乘积 mn
和最大乘积 mx
的。这种方法确保了我们可以找到最大的乘积,而不需要枚举所有可能的子集。
class Solution {
public long maxStrength(int[] nums) {
long mn = nums[0]; // 初始化最小乘积为数组的第一个元素
long mx = mn; // 初始化最大乘积也为数组的第一个元素
for (int i = 1; i < nums.length; i++) {
long x = nums[i]; // 当前遍历到的元素
long oldMn = mn; // 保存当前的最小乘积,以便在更新时使用
long oldMx = mx; // 保存当前的最大乘积,以便在更新时使用
// 更新最小乘积
// 考虑不包括当前元素和包括当前元素的情况
mn = Math.min(Math.min(mn, x), Math.min(oldMn * x, oldMx * x));
// 更新最大乘积
// 考虑不包括当前元素和包括当前元素的情况
mx = Math.max(Math.max(mx, x), Math.max(oldMn * x, oldMx * x));
}
return mx; // 返回最大乘积
}
}