628. 三个数的最大乘积

一、题目

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

示例 1:

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

示例 2:

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

注意:

  1. 给定的整型数组长度范围是[3,104],数组中所有的元素范围是[-1000, 1000]。
  2. 输入的数组中任意三个数的乘积不会超出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%的用户
posted @ 2020-10-19 19:08  球球z  阅读(122)  评论(0)    收藏  举报