1. 程式人生 > >[LeetCode] Maximum Product of Three Numbers 三個數字的最大乘積

[LeetCode] Maximum Product of Three Numbers 三個數字的最大乘積

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

Example 1:

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

Example 2:

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

Note:

  1. The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000].
  2. Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer.

這道題博主剛開始看的時候,心想直接排序,然後最後三個數字相乘不就完了,心想不會這麼Easy吧,果然被OJ無情打臉,沒有考慮到負數和0的情況。這道題給了陣列的範圍,至少三個,那麼如果是三個的話,就無所謂了,直接相乘返回即可,但是如果超過了3個,而且有負數存在的話,情況就可能不一樣,我們來考慮幾種情況,如果全是負數,三個負數相乘還是負數,為了讓負數最大,那麼其絕對值就該最小,而負數排序後絕對值小的都在末尾,所以是末尾三個數字相乘,這個跟全是正數的情況一樣。那麼重點在於前半段是負數,後半段是正數,那麼最好的情況肯定是兩個最小的負數相乘得到一個正數,然後跟一個最大的正數相乘,這樣得到的肯定是最大的數,所以我們讓前兩個數相乘,再和陣列的最後一個數字相乘,就可以得到這種情況下的最大的乘積。實際上我們並不用分情況討論陣列的正負,只要把這兩種情況的乘積都算出來,比較二者取較大值,就能涵蓋所有的情況,從而得到正確的結果,參見程式碼如下:

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

下面這種方法由網友hello_world00提供,找出3個最大的數 || 找出一個最大的和兩個最小的,相乘對比也能得到結果,而且是O(n)的時間複雜度,參見程式碼如下:

解法二:

class Solution {
public:
    int maximumProduct(vector<int>& nums) {
        int mx1 = INT_MIN, mx2 = INT_MIN, mx3 = INT_MIN;
        int mn1 = INT_MAX, mn2 = INT_MAX;
        for (int num : nums) {
            if (num > mx1) {
                mx3 = mx2; mx2 = mx1; mx1 = num;
            } else if (num > mx2) {
                mx3 = mx2; mx2 = num;
            } else if (num > mx3) {
                mx3 = num;
            }
            if (num < mn1) {
                mn2 = mn1; mn1 = num;
            } else if (num < mn2) {
                mn2 = num;
            }
        }
        return max(mx1 * mx2 * mx3, mx1 * mn1 * mn2);
    }
};

參考資料: