LeetCode 628: Maximum Product of Three Numbers (Track Top-3 Max and Top-2 Min)
LeetCode 628ArrayGreedyToday we solve LeetCode 628 - Maximum Product of Three Numbers.
Source: https://leetcode.com/problems/maximum-product-of-three-numbers/
English
Problem Summary
Given an integer array nums, return the maximum product you can get from any three numbers.
Key Insight
Only two candidate products matter:
- Product of the three largest numbers max1 * max2 * max3.
- Product of the largest number and the two smallest numbers max1 * min1 * min2 (because two negatives can become a large positive).
Algorithm
- One pass through nums.
- Track top-3 maximums and top-2 minimums.
- Return max(max1*max2*max3, max1*min1*min2).
Complexity Analysis
Time: O(n).
Space: O(1).
Common Pitfalls
- Only checking the three largest numbers and missing negative-pair cases.
- Sorting first is valid but O(n log n); this problem can be solved in O(n).
- Forgetting integer boundary concerns in languages with fixed integer widths.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public int maximumProduct(int[] nums) {
int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;
int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
for (int x : nums) {
if (x > max1) {
max3 = max2;
max2 = max1;
max1 = x;
} else if (x > max2) {
max3 = max2;
max2 = x;
} else if (x > max3) {
max3 = x;
}
if (x < min1) {
min2 = min1;
min1 = x;
} else if (x < min2) {
min2 = x;
}
}
return Math.max(max1 * max2 * max3, max1 * min1 * min2);
}
}func maximumProduct(nums []int) int {
max1, max2, max3 := math.MinInt32, math.MinInt32, math.MinInt32
min1, min2 := math.MaxInt32, math.MaxInt32
for _, x := range nums {
if x > max1 {
max3 = max2
max2 = max1
max1 = x
} else if x > max2 {
max3 = max2
max2 = x
} else if x > max3 {
max3 = x
}
if x < min1 {
min2 = min1
min1 = x
} else if x < min2 {
min2 = x
}
}
a := max1 * max2 * max3
b := max1 * min1 * min2
if a > b {
return a
}
return b
}class Solution {
public:
int maximumProduct(vector<int>& nums) {
int max1 = INT_MIN, max2 = INT_MIN, max3 = INT_MIN;
int min1 = INT_MAX, min2 = INT_MAX;
for (int x : nums) {
if (x > max1) {
max3 = max2;
max2 = max1;
max1 = x;
} else if (x > max2) {
max3 = max2;
max2 = x;
} else if (x > max3) {
max3 = x;
}
if (x < min1) {
min2 = min1;
min1 = x;
} else if (x < min2) {
min2 = x;
}
}
return max(max1 * max2 * max3, max1 * min1 * min2);
}
};class Solution:
def maximumProduct(self, nums: List[int]) -> int:
max1 = max2 = max3 = -10**9
min1 = min2 = 10**9
for x in nums:
if x > max1:
max3 = max2
max2 = max1
max1 = x
elif x > max2:
max3 = max2
max2 = x
elif x > max3:
max3 = x
if x < min1:
min2 = min1
min1 = x
elif x < min2:
min2 = x
return max(max1 * max2 * max3, max1 * min1 * min2)var maximumProduct = function(nums) {
let max1 = -Infinity, max2 = -Infinity, max3 = -Infinity;
let min1 = Infinity, min2 = Infinity;
for (const x of nums) {
if (x > max1) {
max3 = max2;
max2 = max1;
max1 = x;
} else if (x > max2) {
max3 = max2;
max2 = x;
} else if (x > max3) {
max3 = x;
}
if (x < min1) {
min2 = min1;
min1 = x;
} else if (x < min2) {
min2 = x;
}
}
return Math.max(max1 * max2 * max3, max1 * min1 * min2);
};中文
题目概述
给你一个整数数组 nums,从中选三个数,使它们的乘积最大,返回这个最大乘积。
核心思路
只需要比较两种候选:
- 最大的三个数乘积:max1 * max2 * max3。
- 最大数与最小两个数乘积:max1 * min1 * min2(两个负数可能变成很大的正数)。
算法步骤
- 一次遍历数组。
- 维护三个最大值和两个最小值。
- 返回上述两个候选乘积的较大值。
复杂度分析
时间复杂度:O(n)。
空间复杂度:O(1)。
常见陷阱
- 只看最大的三个数,忽略了“两个负数 + 一个最大正数”的情况。
- 先排序虽然可行,但会变成 O(n log n)。
- 固定宽度整型语言中要注意乘积溢出风险。
多语言参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public int maximumProduct(int[] nums) {
int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;
int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
for (int x : nums) {
if (x > max1) {
max3 = max2;
max2 = max1;
max1 = x;
} else if (x > max2) {
max3 = max2;
max2 = x;
} else if (x > max3) {
max3 = x;
}
if (x < min1) {
min2 = min1;
min1 = x;
} else if (x < min2) {
min2 = x;
}
}
return Math.max(max1 * max2 * max3, max1 * min1 * min2);
}
}func maximumProduct(nums []int) int {
max1, max2, max3 := math.MinInt32, math.MinInt32, math.MinInt32
min1, min2 := math.MaxInt32, math.MaxInt32
for _, x := range nums {
if x > max1 {
max3 = max2
max2 = max1
max1 = x
} else if x > max2 {
max3 = max2
max2 = x
} else if x > max3 {
max3 = x
}
if x < min1 {
min2 = min1
min1 = x
} else if x < min2 {
min2 = x
}
}
a := max1 * max2 * max3
b := max1 * min1 * min2
if a > b {
return a
}
return b
}class Solution {
public:
int maximumProduct(vector<int>& nums) {
int max1 = INT_MIN, max2 = INT_MIN, max3 = INT_MIN;
int min1 = INT_MAX, min2 = INT_MAX;
for (int x : nums) {
if (x > max1) {
max3 = max2;
max2 = max1;
max1 = x;
} else if (x > max2) {
max3 = max2;
max2 = x;
} else if (x > max3) {
max3 = x;
}
if (x < min1) {
min2 = min1;
min1 = x;
} else if (x < min2) {
min2 = x;
}
}
return max(max1 * max2 * max3, max1 * min1 * min2);
}
};class Solution:
def maximumProduct(self, nums: List[int]) -> int:
max1 = max2 = max3 = -10**9
min1 = min2 = 10**9
for x in nums:
if x > max1:
max3 = max2
max2 = max1
max1 = x
elif x > max2:
max3 = max2
max2 = x
elif x > max3:
max3 = x
if x < min1:
min2 = min1
min1 = x
elif x < min2:
min2 = x
return max(max1 * max2 * max3, max1 * min1 * min2)var maximumProduct = function(nums) {
let max1 = -Infinity, max2 = -Infinity, max3 = -Infinity;
let min1 = Infinity, min2 = Infinity;
for (const x of nums) {
if (x > max1) {
max3 = max2;
max2 = max1;
max1 = x;
} else if (x > max2) {
max3 = max2;
max2 = x;
} else if (x > max3) {
max3 = x;
}
if (x < min1) {
min2 = min1;
min1 = x;
} else if (x < min2) {
min2 = x;
}
}
return Math.max(max1 * max2 * max3, max1 * min1 * min2);
};
Comments