传送门 :https://leetcode-cn.com/problems/integer-break/

题目

给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

示例 1:

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

示例 2:

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

说明:你可以假设 n 不小于 2 且不大于 58

解题思路:动态规划

对于的正整数 ,当 时,可以拆分成至少两个正整数的和。令 是拆分出的第一个正整数,则剩下的部分是 ,其中 可以选择不拆或者继续拆分。

  1. - 不拆:`dp[i]=j×(i-j)`
  2. - 拆分:`dp[i]=j×dp[i-j]`

令 表示为将正整数 拆分成至少两个正整数的和之后的最大乘积。 [ 即题目的要求 ]

状态转移方程:

最终得到答案 的值即为将正整数 拆分成至少两个正整数的和之后,这些正整数的最大乘积。

边界情况:
0 不是正整数,1 是最小的正整数,01 都不能拆分,因此 。

复杂度分析

时间复杂度:[LeetCode]Dp343 整数拆分 - 图1

其中 是给定的正整数。对于 2n的每个整数都要计算对应的dp[i] ,计算一个整数对应的 dp 值需要 O(n) 的时间复杂度,因此总时间复杂度是
空间复杂度:[LeetCode]Dp343 整数拆分 - 图2
其中 是给定的正整数。创建一个数组 dp ,返回长度为 n+1

代码

官方代码

  1. class Solution {
  2. public int integerBreak(int n) {
  3. int[] dp = new int[n + 1];
  4. for (int i = 2; i <= n; i++) {
  5. for (int j = 1; j < i; j++) {
  6. dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j]));
  7. }
  8. }
  9. return dp[n];
  10. }
  11. }

解题思路:数学

🚩传送门:https://www.yuque.com/qingxuan-u4juc/leetcode/bus4yx