LC343. 整数拆分

题目: 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

思路

第一反应直接暴力枚举每个拆分方案,然后取乘积比较,但是较大的数对较小的数有包含关系,如4的两种拆分(1,3),(1,1,2),后者的(1,2)也可以看作前者(3)的一种拆分,所以可以发现递推关系 4的结果(拆出一个1的情况)=取最大(1*(3),1*(3的结果)…)
进而泛化为 res(n)=i*max(n-i,res(n-i)) i:1->n/2 (过半后重复)

解题方法 一

直接搜索,自顶向下遍历每一种拆分方式
递归终止条件是n=0/1 此时返回0,如果是已经搜过的方案,返回保存的记录
每一层从1…n/2逐步拆分 更新最大值
把结果保存,降低时间复杂度

复杂度

时间复杂度:

O ( n ) O(n) O(n)

Code

class Solution {
    int[] dp;
    public int integerBreak(int n) {
        dp=new int[n+1];
        return dfs(n);
    } 
    int dfs(int n){
        if(n<=1) return 0;
        if(dp[n]!=0) return dp[n];

        int ans=Integer.MIN_VALUE;
        for(int i=1;i<=n/2;i++){
            ans= Math.max(ans,i*Math.max(dfs(n-i),n-i));
        }
        dp[n]=ans;
        return dp[n];
    }
}

解题方法 二

动态规划,自底向上迭代 dp[i]表示划分数字i时它的组分最大乘积
初始化 dp[2] =1 (dp[0]/[1]默认为0)
每一层从1…n/2逐步拆分 更新最大值

复杂度

时间复杂度:

O ( n 2 ) O(n^2) O(n2)

Code

class Solution {
    public int integerBreak(int n) {
        int[] dp=new int[n+1];//dp[i]表示划分数字为i时它的组分最大乘积
        //初始化
        dp[2]=1;
        for(int idx=3;idx<=n;idx++){
            for(int cut=1;cut<=n/2&&cut<idx;cut++){
                dp[idx]=Math.max(dp[idx],cut*Math.max(idx-cut,dp[idx-cut]));
            }
        }
        return dp[n];
    }
}
  • 17
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vⅤ_Leon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值