题目描述:
给你一个整型数组
nums
,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
示例 1:
输入:nums = [1,2,3]
输出:6
示例 2:
输入:nums = [1,2,3,4]
输出:24
示例 3:
输入:nums = [-1,-2,-3]
输出:-6
解法一:排序
解题思路:
想要得到一个数组中三个数组成的最大乘积,就要找到数组中的三个最大数,但是还要考虑到数组中是否存在负数。因此,基于数组按升序排列的前提下,分为以下情况:
(1)如果数组中全是正数,则直接选择排序数组的后三个数作为乘积。
(2)如果数组中全是非正数,则同样也是选择排序数组后三个数作为乘积。
(3)如果数组中既有负数,也有正数,则选择两个最小负数和一个最大正数作为乘积。
代码如下:
class Solution {
public int maximumProduct(int[] nums) {
//对数组进行排序
Arrays.sort(nums);
//获取数组长度
int n = nums.length;
//计算两个最小值和一个最大值的乘积
int val1 = nums[0] * nums[1] * nums[n-1];
//计算三个最大值之间的乘积
int val2 = nums[n-1] * nums[n-2] * nums[n-3];
return Math.max(val1, val2);
}
}
解法二:线性扫描
解题思路:
解法一中,不同的排序算法的时间复杂度会影响整体的执行时间,因此可以通过线性扫描的方式降低时间复杂度。实际上,我们只要求出数组中最大的三个数以及最小的两个数即可。
代码如下:
class Solution {
public int maximumProduct(int[] nums) {
// 最小的和第二小的
int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
// 最大的、第二大的和第三大的
int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;
//线性扫描
for (int x : nums) {
if (x < min1) {
min2 = min1;
min1 = x;
} else if (x < min2) {
min2 = x;
}
if (x > max1) {
max3 = max2;
max2 = max1;
max1 = x;
} else if (x > max2) {
max3 = max2;
max2 = x;
} else if (x > max3) {
max3 = x;
}
}
return Math.max(min1 * min2 * max1, max1 * max2 * max3);
}
}