整数拆分

122 阅读1分钟

题目描述:

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

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

image.png

思考

  1. dp[i]:表示将i拆分之后获得的最大的乘积

  2. 递推公式: 可以想 dp[i]最⼤乘积是怎么得到的呢?

    其实可以从1遍历j,然后有两种渠道得到dp[i]:

    1. j * (i - j) 直接相乘 (拆分为两个数)

    2. j * dp[i - j],相当于是拆分(i - j),j怎么就不拆分呢? j是从1开始遍历,拆分j的情况,在遍历j的过程中其实都计算过了。(拆分为3个或3个以上的数字)

    故可以得到递推公式:dp[i]=max((i - j) * j, dp[i - j] * j)

  3. 初始化:i=0,i=1时,无法进行拆分,故拆分之后不存在最大乘积,将dp[0],dp[1]初始化为0;当i=2时,可以拆分为1+1,故dp[2]=1.

  4. 遍历顺序:

    1. dp[i] 是依靠 dp[i - j]的状态,所以遍历i⼀定是从前向后遍历,先有dp[i - j]再有dp[i];
    2. 枚举j的时候,是从1开始的。i是从3开始,这样dp[i - j]就是dp[2]正好可以通过我们初始化的数值求出来。
  5. 打印dp数组。

代码

var integerBreak = function(n) {
    var dp=[];
    //初始化
    dp[0]=0;
    dp[1]=0;
    dp[2]=1;

    for(let i=3;i<=n;i++){
        let temp=0;//存储每次拆分的乘积
        // 对i进行拆分,从j=1开始,到i-1结束
        for(let j=1;j<i;j++){
            dp[i]=Math.max(temp,Math.max(j*(i-j),j*dp[i-j]));
            temp=dp[i];
        }
    }
    return dp[n];
};

结果

image.png