Intuition¶
The maximum product of three numbers has only two possible forms:
- the three largest numbers, or
- the largest number multiplied by the two smallest numbers, which may both be negative.
We can track the three largest and two smallest values in one pass.
Approach: Track Five Extreme Values¶
- Maintain
max1 >= max2 >= max3, the three largest values seen. - Maintain
min1 <= min2, the two smallest values seen. - For each number, update both groups of extremes.
- Return the larger of
max1 * max2 * max3andmin1 * min2 * max1.
Complexity¶
- Time complexity: $$O(n)$$, where
nisnums.length. - Space complexity: $$O(1)$$.
Code¶
Go¶
import "math"
func maximumProduct(nums []int) int {
max1, max2, max3, min1, min2 := math.MinInt32, math.MinInt32, math.MinInt32, math.MaxInt32, math.MaxInt32
for _, i := range nums {
if i > max1 {
max3 = max2
max2 = max1
max1 = i
} else if i > max2 {
max3 = max2
max2 = i
} else if i > max3 {
max3 = i
}
if i < min1 {
min2 = min1
min1 = i
} else if i < min2 {
min2 = i
}
}
return max(max1 * max2 * max3, min1 * min2 * max1)
}
Rust¶
impl Solution {
pub fn maximum_product(nums: Vec<i32>) -> i32 {
let (mut max1, mut max2, mut max3, mut min1, mut min2) = (i32::MIN, i32::MIN, i32::MIN, i32::MAX, i32::MAX);
for num in nums {
if num > max1 {
max3 = max2;
max2 = max1;
max1 = num;
} else if num > max2 {
max3 = max2;
max2 = num;
} else if num > max3 {
max3 = num;
}
if num < min1 {
min2 = min1;
min1 = num;
} else if num < min2 {
min2 = num;
}
}
(max1 * max2 * max3).max(min1 * min2 * max1)
}
}