628. 三个数的最大乘积
一、题目
给定一个整型数组,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
示例 1:
输入: [1,2,3]
输出: 6
示例 2:
输入: [1,2,3,4]
输出: 24
注意:
- 给定的整型数组长度范围是[3,104],数组中所有的元素范围是[-1000, 1000]。
- 输入的数组中任意三个数的乘积不会超出32位有符号整数的范围。
二、题解
- 把负数区分开
- 找到非负数的最大的三个值max1,max2,max3
- 找到负数的最小的两个值min1,min2,min3 和最大的三个值max1,max2,max3
- 最大乘积为 非负数max1 * (非负数max2 * 非负数max3)与非负数max1 * (负数min1 * 负数min2)之间较大的数
- 排除一种特殊情况,若全是负数 最大乘积为 负数max1 * 负数max2 * 负数max3
class Solution {
public int maximumProduct(int[] nums) {
int posMax1 = 0;
int posMax2 = 0;
int posMax3 = 0;
int negMin1 = 0;
int negMin2 = 0;
int negMax1 = Integer.MIN_VALUE;
int negMax2 = Integer.MIN_VALUE;
int negMax3 = Integer.MIN_VALUE;
boolean havePos = false;
int result = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i]>=0){
havePos = true;
if(nums[i]>=posMax1) {
posMax3 = posMax2;
posMax2 = posMax1;
posMax1 = nums[i];
} else if (nums[i]>=posMax2) {
posMax3 = posMax2;
posMax2 = nums[i];
} else if (nums[i]>=posMax3) {
posMax3 = nums[i];
}
} else {
if (nums[i]<negMin1) {
negMin2 = negMin1;
negMin1 = nums[i];
} else if (nums[i]<negMin2) {
negMin2 = nums[i];
}
if (!havePos) {
if(nums[i]>=negMax1) {
negMax3 = negMax2;
negMax2 = negMax1;
negMax1 = nums[i];
} else if (nums[i]>=negMax2) {
negMax3 = negMax2;
negMax2 = nums[i];
} else if (nums[i]>=negMax3) {
negMax3 = nums[i];
}
}
}
}
if (!havePos) {
result = negMax1 * negMax2 * negMax3;
} else {
result = Math.max(posMax1*negMin1*negMin2,posMax1*posMax2*posMax3);
}
return result;
}
}
- 时间复杂度O(n)
- 空间复杂度O(1)
- 执行用时:4 ms, 在所有 Java 提交中击败了73.98%的用户
- 内存消耗:39.4 MB, 在所有 Java 提交中击败了99.88%的用户
改进
- 上述解法第一步剥离了负数
- 而最终结果的三种可能性为
- 非负数max1 * 非负数max2 * 非负数max3
- 非负数max1 * 负数min1 * 负数min2
- 负数max1 * 负数max2 * 负数max3——与第一种情况相同都是三个最大值
- 本质上是两种情况
- 所有数max1 * 所有数max2 * 所有数max3
- 所有数max1 * 所有数min1 * 所有数min2
- 因此不剥离负数,直接找出所有数max1,max2,max3,min1,min2
class Solution {
public int maximumProduct(int[] nums) {
long Max1 = Long.MIN_VALUE;
long Max2 = Long.MIN_VALUE;
long Max3 = Long.MIN_VALUE;
long Min1 = Long.MAX_VALUE;
long Min2 = Long.MAX_VALUE;
long result = 0;
for (int i = 0; i < nums.length; i++) {
//找到最大的三个值
if (nums[i]>=Max1) {
Max3 = Max2;
Max2 = Max1;
Max1 = nums[i];
} else if (nums[i]>=Max2) {
Max3 = Max2;
Max2 = nums[i];
} else if (nums[i]>=Max3) {
Max3 = nums[i];
}
//找到最小的两个值
if (nums[i]<Min1) {
Min2 = Min1;
Min1 = nums[i];
} else if (nums[i]<Min2) {
Min2 = nums[i];
}
}
result = Math.max(Max1*Max2*Max3,Max1*Min1*Min2);
return (int)result;
}
}
- 时间复杂度O(n)
- 空间复杂度O(1)
- 执行用时:4 ms, 在所有 Java 提交中击败了73.98%的用户
- 内存消耗:39.2 MB, 在所有 Java 提交中击败了100.00%的用户