整数拆分

343. 整数拆分

给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积 。

示例 1:

输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。

示例 2:

输入: n = 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。

提示:

2 <= n <= 58

动态规划

确定dp数组及下标的含义

dp[i]表示拆分数字 i ,可以得到的最大乘积

确定递推公式

数字 i 拆分后的最大乘积可以有两种方式得到

j 从1遍历到 i-1

1、如果将数字 i 分成两份,乘积为j*(i - j)

2、如果将数字 i 分成两份及以上,乘积为j *dp[i - j]

故递推公式为dp[i] = Math.max(dp[i], Math.max(j*(i - j), dp[i - j] *j))

为什么还要和dp[i]比较?因为在遍历 j 的过程中,要取dp[i]的最大值

初始化dp数组

只用初始化dp[2] =1 ,表示拆分数字2最大乘积为,而dp[0],dp[1]没有意义

确定遍历顺序

1
2
3
4
5
for(int i = 3; i <= n; i++){
for(int j = 1; j <= i-1; j++){
dp[i] = Math.max(dp[i], Math.max(j*(i-j), dp[i-j]*j) );
}
}

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public int integerBreak(int n) {
//dp[i]表示拆分数字i的最大乘积
int[] dp = new int[n+1];
//dp[i]可以由两种路径达到, j从1遍历到i-1
//1、dp[i] = j * (i-j) ,即i分成两个数
//2、dp[i] = dp[i-j] * j ,即i分成两个以上的数
dp[2] = 1; //dp[0]和dp[1]默认不存在
for(int i = 3; i <= n; i++){
for(int j = 1; j <= i-1; j++){
dp[i] = Math.max(dp[i], Math.max(j*(i-j), dp[i-j]*j) );
}
}
return dp[n];
}
}
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(n)

整数拆分
http://example.com/2023/01/18/算法/动态规划/6. 整数拆分/
作者
PALE13
发布于
2023年1月18日
许可协议