You are given a positive integer n
(where n ≥ 2
). You must break n
into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.
n
cannot remain whole).
Example: For n = 10
, you can split it as 3 + 3 + 4, and the product is 3 × 3 × 4 = 36 (which is the maximum possible).
The problem asks us to split a number into at least two positive integers such that their sum is n
and their product is as large as possible.
The brute-force way would be to try all possible ways to split n
and compute the product for each, but this is inefficient for large n
because the number of splits grows rapidly.
To optimize, we need to look for patterns. For example, splitting numbers into as many 3s as possible tends to give a bigger product. Why? Because for any integer n
, the product of numbers that sum to n
is maximized when those numbers are as close to e
(Euler's number, about 2.718) as possible. Since we can only use integers, 2 and 3 are the best choices, and 3 is usually better.
So, we shift from brute-force enumeration to a mathematical or dynamic programming approach that exploits this insight.
dp
where dp[i]
stores the maximum product for integer i
.i
from 2 to n
, we try every possible first split j
(from 1 to i-1
), and consider two cases:
j
and i - j
(no further split).j
and dp[i - j]
(split i-j
further).j
and set it as dp[i]
.dp[n]
will be the answer.n > 4
, the best strategy is to break n
into as many 3s as possible. If the remainder is 1, we adjust by using a 4 instead (because 2×2 > 3×1).
Let's walk through the example of n = 10
using the DP approach:
dp[2] = 1
(since 1 + 1 = 2, product is 1).i = 3
:
dp[3] = 2
.dp
up to dp[10]
:
i = 10
, we check all splits:
The greedy approach would simply compute: 10 = 3 + 3 + 4, and multiply.
n
.
i
(up to n
), we try all splits j
(up to i-1
), so time complexity is O(n2). Space complexity is O(n) for the DP array.
Thus, the greedy approach is optimal for large n
.
The Integer Break problem challenges us to split a number into a sum of at least two positive integers to maximize their product. While brute-force is impractical, dynamic programming offers a clear, step-by-step solution, and mathematical insight reveals that breaking numbers into mostly 3s yields the highest product. The greedy approach is the most efficient and elegant, leveraging mathematical properties for a constant-time solution.
class Solution:
def integerBreak(self, n: int) -> int:
if n == 2:
return 1
if n == 3:
return 2
product = 1
while n > 4:
product *= 3
n -= 3
product *= n
return product
class Solution {
public:
int integerBreak(int n) {
if (n == 2) return 1;
if (n == 3) return 2;
int product = 1;
while (n > 4) {
product *= 3;
n -= 3;
}
product *= n;
return product;
}
};
class Solution {
public int integerBreak(int n) {
if (n == 2) return 1;
if (n == 3) return 2;
int product = 1;
while (n > 4) {
product *= 3;
n -= 3;
}
product *= n;
return product;
}
}
var integerBreak = function(n) {
if (n === 2) return 1;
if (n === 3) return 2;
let product = 1;
while (n > 4) {
product *= 3;
n -= 3;
}
product *= n;
return product;
};