【前端er每日算法】动态规划2题--343整数拆分/96

101 阅读1分钟

题目一 343. 整数拆分

思路

  1. 确定含义:dp[i]是指拆分数字i,可以得到的最大乘积dp[i]

  2. 递推公式

  3. dp[i] = max((i-j)*j, dp[i-j]*j)

    • j * (j-j)直接相乘
    • j * dp[i-j]相当于拆分i-j, 包含3个数相乘,4个数相乘,... i-j个数相乘
  4. dp初始化:dp[2] = 1

  5. 遍历顺序:从前向后

这个递归公式想不到。。。不是很懂

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

题目二 96. 不同的二叉搜索树

思路

  1. dp[i]: i个节点构造不同二叉搜索树的个数
  2. 递推公式:dp[i] += dp[j - 1] * dp[i - j],代表分别以1到j为头节点构造的二叉搜索树的和。那以j为头结点的二叉树,左边有j-1个节点,值就是dp[j - 1], 右边有i-j个节点,就是dp[i-j],所以依次把所有能构造出来的子树的和求出来就是dp[i]的结果
  3. 初始值:dp[0] = dp[1] = 1;
  4. 循环顺序,因为递推公式是依据前面的值计算出来的,所以是从前向后遍历,从2开始计算,内层循环j从1到i(包含i),依次求和
var numTrees = function(n) {
    // 比n大一的数组
    const dp = new Array(n + 1).fill(0);
    dp[0] = 1;
    dp[1] = 1;
    for (let i = 2; i <= n; i++) {
        for (let j = 1; j <= i; j++) {
            dp[i] += dp[j-1]* dp[i-j];
        }
    }
    return dp[n];
};