LeetCode C++ 628. Maximum Product of Three Numbers【Array/Math】简单

Given an integer array nums, find three numbers whose product is maximum and return the maximum product.

Example 1:

Input: nums = [1,2,3]
Output: 6

Example 2:

Input: nums = [1,2,3,4]
Output: 24

Example 3:

Input: nums = [-1,-2,-3]
Output: -6

Constraints:

  • 3 <= nums.length <= 104
  • -1000 <= nums[i] <= 1000

题意:给定一个整型数组,在数组中找出由三个数组成的最大乘积,并输出这个乘积。注意,输入的数组中任意三个数的乘积不会超出32位有符号整数的范围。


分类讨论,可知数组有几种情况:

  • 全非负数、全非正数:最大三个数相乘
  • 有正、有负、有零:最大三个数相乘,或者最小两个数相乘再乘以最大一个数

解法1 排序

先排序,之后很容易得到最大值、最小值等:

class Solution {
public:
    int maximumProduct(vector<int>& nums) {
        if (nums.size() == 3) return nums[0] * nums[1] * nums[2];
        sort(nums.begin(), nums.end());
        int n = nums.size() - 1;
        if (nums[n] <= 0 || nums[0] >= 0) return nums[n] * nums[n - 1] * nums[n - 2]; //都<=0或>=0
        return max(nums[n] * nums[n - 1] * nums[n - 2], nums[n] * nums[0] * nums[1]);
    }
};

时间复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn) ,执行效率如下:

执行用时:164 ms, 在所有 C++ 提交中击败了19.24% 的用户
内存消耗:27.5 MB, 在所有 C++ 提交中击败了6.24% 的用户

解法2 直接遍历

直接遍历整个数组,得到最小值、次小值、最大值、次大值、再次值:

class Solution {
public:
    int maximumProduct(vector<int>& nums) {
        if (nums.size() == 3) return nums[0] * nums[1] * nums[2];
        int min1 = INT_MAX, min2 = INT_MAX; //最小值、次小值
        int max1 = INT_MIN, max2 = INT_MIN, max3 = INT_MIN; //最大值、次大值、再次值
        int n = nums.size();
        for (int i = 0; i < n; ++i) {
            int cur = nums[i];
            if (cur <= min1) { //更新最小值、次小值
                min2 = min1;
                min1 = cur;
            } else if (cur <= min2) //更新次小值
                min2 = cur;
            if (cur >= max1) { //更新最大值、次大值、再次值
                max3 = max2;
                max2 = max1;
                max1 = cur;
            } else if (cur >= max2) { //更新次大值、再次值
                max3 = max2;
                max2 = cur;
            } else if (cur >= max3) //更新再次值
                max3 = cur;
        }
        return max(max1 * max2 * max3, min1 * min2 * max1); //两种情况:最大三个数相乘、最大一个数*最小两个数
    }
};

线性解法,效率不错:

执行用时:76 ms, 在所有 C++ 提交中击败了96.87% 的用户
内存消耗:27.5 MB, 在所有 C++ 提交中击败了6.24% 的用户

对应的Java代码如下:

class Solution {
    public int maximumProduct(int[] nums) {
        if (nums.length == 3) return nums[0] * nums[1] * nums[2];
        int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE; //min1 < min2
        int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE; //max1 > max2 > max3
        for (int v : nums) {
            if (v < min1) {
                min2 = min1;
                min1 = v;
            } else if (v < min2) min2 = v;
            if (v > max1) {
                max3 = max2;
                max2 = max1;
                max1 = v;
            } else if (v > max2) {
                max3 = max2;
                max2 = v;
            } else if (v > max3) max3 = v;
        }
        return Math.max(max1 * max2 * max3, min1 * min2 * max1);
    }
}

运行效率如下:

执行用时:2 ms, 在所有 Java 提交中击败了99.13% 的用户
内存消耗:39.7 MB, 在所有 Java 提交中击败了75.25% 的用户
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

memcpy0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值