🚩传送门:牛客题目
题目
给你一个整型数组nums
,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
要求:时间复杂度 ,空间复杂度
示例 1:
输入:nums = [1,2,3] 输出:6
示例 2:
输入:nums = [1,2,3,4] 输出:24
示例 3:
输入:nums = [-1,-2,-3] 输出:-6
解题思路1:排序
首先将数组排序。
- 如果数组中全是正数,则排序后最大的三个数相乘即为最大乘积;(正的最多)
- 如果数组中全是负数,则排序后最大的三个数相乘即为最大乘积;(负的最少)
- 如果数组中有正数有负数,则最大乘积既可能是三个最大正数的乘积,也可能是两个最小负数(即绝对值最大)与最大正数的乘积。
综上,我们在给数组排序后,分别求出三个最大正数的乘积,以及两个最小负数与最大正数的乘积,二者之间的最大值即为所求答案。
复杂度分析
时间复杂度:,其中
是数组长度。排序需要
的时间。
空间复杂度:,主要为排序的空间开销。
官方代码
class Solution {
public long maximumProduct(int[] nums) {
Arrays.sort(nums);
long n = nums.length;
return Math.max(nums[0] * nums[1] * nums[n - 1], nums[n - 3] * nums[n - 2] * nums[n - 1]);
}
}
解题思路2:线性扫描
在方法一中,我们实际上只要求出数组中最大的三个数以及最小的两个数,因此我们可以不用排序,用线性扫描直接得出这五个数。
复杂度分析
时间复杂度:,其中
是数组长度,我们仅需遍历数组一次。
空间复杂度:
官方代码
class Solution {
public long maximumProduct(int[] nums) {
// 最小的和第二小的
long min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
// 最大的、第二大的和第三大的
long max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;
for (int num : nums) {
if (num > max1) { // ==========啥,你比老大的值还大=======
max3 = max2; // 原老二委屈一下你,去做老三吧,难受...
max2 = max1; // 原老大委屈一下你,去做老二吧,难受...
max1 = num; // 大哥快请上座!!!
} else if (num > max2) { // ==========啥,你比老二的值还大=======
max3 = max2; // 原老二委屈一下你,去做老三吧,难受...
max2 = num; // 二哥快请上座!!!
} else if (num > max3) { // ==========哎,你比老三的值还大=======
max3 = num; // 三哥快请上座!!!
}
if (num < min1) { // ==========啥,你比老幺的值还小=======
min2 = min1; // 原老幺委屈一下你,去做二幺吧,难受...
min1 = num; // 老幺快请上座!!!
} else if (num < min2) { // ==========啥,你比二幺的值还小=======
min2 = num; // 二幺快请上座!!!
}
}
return Math.max(min1 * min2 * max1, max1 * max2 * max3);
}
}