題目: 給定正整數 n (n ≥ 2),將其拆分為 至少兩個 正整數之和,使乘積最大化。返回最大乘積。
示例: n=2 → 1 (1+1);n=10 → 36 (3+3+4)
x > 0,拆分為 e (≈2.718) 乘積最大 (微積分極值)。e 的是 3 (其次是 2)。class Solution {
public int integerBreak(int n) {
if (n == 2) return 1;
if (n == 3) return 2;
int quotient = n / 3;
int remainder = n % 3;
if (remainder == 0) {
return (int) Math.pow(3, quotient);
} else if (remainder == 1) {
// 3+1 → 2+2,少一個 3,多兩個 2
return (int) Math.pow(3, quotient - 1) * 4;
} else { // remainder == 2
return (int) Math.pow(3, quotient) * 2;
}
}
}
Math.pow 對數時間 (或視為 O(1) 硬件指令)。dp[i] 表示整數 i 拆分後的最大乘積 (i ≥ 2)。
dp[i] = max( j * (i-j), j * dp[i-j] ) for j = 1..i-1
j * (i-j):直接拆成兩塊不再拆。j * dp[i-j]:拆成兩塊,第二塊繼續最優拆分。class Solution {
public int integerBreak(int n) {
int[] dp = new int[n + 1];
dp[2] = 1;
for (int i = 3; i <= n; i++) {
for (int j = 1; j < i; j++) {
dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j]));
}
}
return dp[n];
}
}
class Solution {
public int integerBreak(int n) {
if (n == 2) return 1;
if (n == 3) return 2;
int product = 1;
while (n > 4) { // n=4 時 2+2=4 不再拆分獲利
product *= 3;
n -= 3;
}
product *= n; // 剩餘 n (2, 3, 或 4) 直接相乘
return product;
}
}
邏輯等價於數學公式,循環拆 3,剩餘 2/3/4 直接乘入。代碼簡潔,無 Math.pow 精度擔憂。
| n | 拆分 | 乘積 | 說明 |
|---|---|---|---|
| 2 | 1+1 | 1 | 特例 |
| 3 | 2+1 | 2 | 特例 |
| 4 | 2+2 | 4 | 3+1=3 < 4,不拆 3 |
| 5 | 3+2 | 6 | >5 |
| 6 | 3+3 | 9 | >2+2+2=8 |
| 7 | 3+2+2 | 12 | >3+4=12 (同) |
| 8 | 3+3+2 | 18 | |
| 10 | 3+3+4 | 36 | 示例 |
| 58 | 18個3 + 4 | 3^18 * 4 | 大數驗證 |
e),再回映整數域 (3)。n > 4。掌握「盡可能拆 3,餘 1 換 2+2」的核心規律與 O(1) 實現,不僅能秒殺此題,更能培養從數學本質穿透算法表象的核心競爭力。