力扣javascript刷题343——动态规划之整数拆分

这几天有在开始投暑期实习的简历,可能确实是投的太晚了,好多厂都没有hc了,阿里简历面都没过(感觉是kpi面试),被深深打击到了呜呜呜,花了两天整理情绪,重新出发,下篇文章针对阿里简历面的问题进行重新整理。

很久没有刷题了,今天遇到一个动态规划的问题,代码随想录讲的不是很清晰,然后我看了下网上的解释,结合代码随想录的知识重新进行了整理;

首先先看题目:
力扣javascript刷题343——动态规划之整数拆分_第1张图片
其实动态规划的问题,其实就是把一个问题拆解成若干个子问题,先解决子问题,然后从这些子问题出发得到原问题的解。

针对上面这个问题,我们现在已经拿到正整数n,当n大于等于2的时候可以拆成至少两个正整数的和。令x是拆分出的第一个正整数(取值范围在1~(n-1)),那么剩下的部分就是n-x
n-x有两种情况:

  1. 不可以继续拆分,那么乘积就是x*(n-x)
  2. 可以继续拆分成至少两个正整数的和,那么乘积就是x*(n-x)的乘积最大化,将子问题求得解即2到n的所有乘积最大化存入数组dp[n]中,那么乘积就是x*dp[n-x]

其实光看上面这段话还是很难让人理解:
简单来说,就是我们自己创建一个数组dp,i表示从1到n的数字,dp[i]表示分解数字i可以得到的最大乘积,其实这就是一个迭代递归的过程,那么我们可以知道dp[0]和dp[1]是没有初始值的,因为0和1不可以拆分,所以我们可以从dp[2]开始设置初始值,dp[2]=1(因为2=1+1),那么接下来就应该从i=3开始遍历

怎么确定递推公式呢?
我们从1到n开始遍历,每次遍历i,我们都要计算dp[i]的值,就相当于去遍历里再套一个遍历j,遍历1到i-1的值,然后取拆分中的乘积最大的情况,这里存在两种情况,一种是对i拆分成两个数,那么dp[i]=(i-j)*j;第二种是对i进行拆分成多个数,那么dp[i]=dp[i-j]*j

然后取最大的值就好啦(确实这个题不太好理解,可能要看好几遍才能真的理解,如果看了好几遍文字依旧是一知半解,可以对照着代码一起看)

/**
 * @param {number} n
 * @return {number}
 */
var integerBreak = function(n) {
    var dp=Array(n+1).fill(0);
    dp[2]=1;
    for(var i=3;i<=n;i++){
        for(var j=1;j<i-1;j++){
            dp[i]=Math.max(dp[i],Math.max((i-j)*j,dp[i-j]*j));
        }
    }
    return dp[n];
};

你可能感兴趣的:(javascript,前端,开发语言)