一、题目
一个小组的最大实力值
二、代码
做出来咯🎉🎉🎉
// 贪心
class Solution {
public long maxStrength(int[] nums) {
Arrays.sort(nums);
long res = 1;
int len = nums.length;
// 先算正数乘积,不用筛选,都需要
int i= len-1;
// 这里注意一下判断条件的顺序,要让i>=0在前,防止发生nums[i]数组越界的情况,具体可通过示例[9,6,3]验证
while(i>=0 && nums[i]>0) {
res = res*(long)nums[i];
i--;
}
// 再算负数乘机,负数要从绝对值大的开始乘,要乘最大偶数个数(所以一次性就乘俩)
// 判断条件-两个数内任意一个为0或下标为i都停止循环
int j = 0;
// 这里注意一下判断条件的顺序,要让j<i在前,防止发生j+1数组越界的情况,具体可通过示例2验证
while(j<i && nums[j]!=0 && nums[j+1]!=0) {
res = res*(long)nums[j]*(long)nums[j+1];
j = j+2;
}
// 经过3次更改,补充剩余较为特殊情况,分别为:
// [0,-1]
// [-9]
// [-4,1]
if(i==len-1 && j==0) {
for(int r=0;r<len;r++) {
res = res*nums[r];
}
}
return res;
}
}
效率
三、题解
动态规划
dp[i]表示 0~i 长度的数组最大实力,因为有正有负,所以对于当前nums[i]来说,前面最大的值会影响结果,最小的值也会影响结果。毕竟负数乘当前nums[i]也可能变成最大值。 综上,影响结果的一共有三个值:min(dp[i - 1]), max(dp[i - 1]), nums[i]; 即可得到当前长度dp[i]的最大最小值:
class Solution {
public long maxStrength(int[] nums) {
long max = nums[0], min = nums[0];
for (int i = 1; i < nums.length; ++i) {
long tmpMax = Math.max(Math.max(nums[i], max), Math.max(nums[i] * max, nums[i] * min));
long tmpMin = Math.min(Math.min(nums[i], min), Math.min(nums[i] * max, nums[i] * min));
max = tmpMax;
min = tmpMin;
}
return max;
}
}
来源:力扣(LeetCode)
效率
虽然效率和我自己代码没差多少,但从代码量和思路清晰度来说还是更优一些