🚩传送门:https://leetcode-cn.com/problems/maximum-product-of-three-numbers/

题目

给你一个整型数组 nums ,在数组中找出由三个数组成的最大乘积,并输出这个乘积。

示例 1:

输入:nums = [1,2,3] 输出:6

示例 2:

输入:nums = [1,2,3,4] 输出:24

示例 3:

输入:nums = [-1,-2,-3] 输出:-6

解题思路:排序

首先将数组排序。

  1. 如果数组中全是非负数num≥0),则排序后最大的三个数相乘即为最大乘积;
  2. 如果数组中全是非正数(num≤0),则排序后最大的三个数相乘即为最大乘积。
  3. 如果数组中有正有负
    • 最大乘积可能是三个最大正数的乘积
    • 最大乘积可能是两个最小负数(即绝对值最大)与最大正数的乘积。

综上,我们在给数组排序后,分别求出三个最大正数的乘积,以及两个最小负数与最大正数的乘积,二者之间的最大值即为所求答案。

复杂度分析

时间复杂度:[LeetCode]Ar628. 三个数的最大乘积 - 图1,其中 [LeetCode]Ar628. 三个数的最大乘积 - 图2 是数组 [LeetCode]Ar628. 三个数的最大乘积 - 图3 的长度 。

空间复杂度:[LeetCode]Ar628. 三个数的最大乘积 - 图4[LeetCode]Ar628. 三个数的最大乘积 - 图5,由排序的空间开销决定。

官方代码

  1. class Solution {
  2. public int maximumProduct(int[] nums) {
  3. Arrays.sort(nums);
  4. int n = nums.length;
  5. return Math.max(nums[0] * nums[1] * nums[n - 1], nums[n - 3] * nums[n - 2] * nums[n - 1]);
  6. }
  7. }

解题思路:线性扫描

实际上只要求出数组中最大的三个数以及最小的两个数,因此可以不用排序,线性扫描出这五个数。

复杂度分析

时间复杂度:[LeetCode]Ar628. 三个数的最大乘积 - 图6,其中 [LeetCode]Ar628. 三个数的最大乘积 - 图7 是数组 [LeetCode]Ar628. 三个数的最大乘积 - 图8 的长度 。

空间复杂度:[LeetCode]Ar628. 三个数的最大乘积 - 图9

官方代码

  1. class Solution {
  2. public int maximumProduct(int[] nums) {
  3. // 最小的和第二小的
  4. int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
  5. // 最大的、第二大的和第三大的
  6. int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;
  7. for (int x : nums) {
  8. //1.如果比最小的小就是最小的
  9. if (x < min1) {
  10. min2 = min1;
  11. min1 = x;
  12. }
  13. //2.如果不小于最小的但是比第二小的小就是第二小
  14. else if (x < min2) {
  15. min2 = x;
  16. }
  17. //3.如果比最大的大就是最大的
  18. if (x > max1) {
  19. max3 = max2;
  20. max2 = max1;
  21. max1 = x;
  22. }
  23. //4.如果不大于最大的但是比第二大的大就是第二大
  24. else if (x > max2) {
  25. max3 = max2;
  26. max2 = x;
  27. }
  28. //5.如果不大于最大、第二大的但是比第三大的大就是第三大
  29. else if (x > max3) {
  30. max3 = x;
  31. }
  32. }
  33. //6.比较返回结果
  34. return Math.max(min1 * min2 * max1, max1 * max2 * max3);
  35. }
  36. }