LeetCode 343:整数拆分
给定一个正整数 n,将其拆分为 k 个正整数的和(k >= 2),并使这些整数的乘积最大化。返回你可以获得的最大乘积。
示例
输入: n = 2 输出: 1 解释: 2 = 1 + 1, 1 × 1 = 1。
输入: n = 10 输出: 36 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
提示:
2 <= n <= 58
思路分析
对于正整数 n,当 n ≥ 2 时,可以拆分成至少两个正整数的和。令 k 是拆分出的第一个正整数,则剩下的部分是 n - k。n - k 可以不继续拆分,或者继续拆分成至少两个正整数的和。这是一个典型的问题分解场景,因此想到使用动态规划。
由于每个正整数对应的最大乘积取决于比它小的正整数对应的最大乘积,我们可以定义 dp[i] 为数字 i 拆分后的最大乘积。在计算 dp[i] 时,我们需要遍历所有可能的拆分点 j(从 1 到 i-1)。
这里有个关键点:对于拆分点 j,剩下的部分 i-j 有两种选择:
- 不再拆分,直接相乘:
j * (i - j) - 继续拆分,利用之前计算好的最优解:
j * dp[i - j]
我们要取这两种情况中的最大值,并更新 dp[i]。
代码实现
import java.util.Arrays;
public class Solution {
public static void main(String[] args) {
// 测试用例
System.out.println(integerBreak(10));
}
public static int integerBreak(int n) {
if (n == 2) {
return 1;
}
// dp[i] 表示数字 i 拆分后的最大乘积
[] res = [n + ];
res[] = ;
res[] = ;
res[] = ;
( ; i < res.length; i++) {
( ; j < i; j++) {
res[i] = Math.max(res[i], Math.max((i - j) * j, res[i - j] * j));
}
}
res[n];
}
}

