算法练习day35

75 阅读1分钟

一、整数拆分

五部曲

  1. dp[i]代表数字i,拆分后得到的最大乘积
  2. 递归公式:有两种方式得到dp[i],j * (i - j) 拆两个,或者j * dp[i-j],拆两个以上,dp[i] = Math.max(dp[i], j * (i - j), j * dp[i-j])
  3. dp初始化, 从2开始才有意义, dp[2] = 1
  4. 遍历顺序: 从前往后,拆分一个数n使其乘积最大,一定是拆分成m个近似相同的子树,m大于等于2,所以只需要遍历到 m / 2
  5. 举例
/**
 * @param {number} n
 * @return {number}
 */
var integerBreak = function(n) {
    let dp = new Array(n + 1).fill(0)
    dp[2] = 1
    for(let i = 3; i <= n; i++) {
        for(let j = 1; j <= i / 2; j++) {
            dp[i] = Math.max(dp[i], j * (i-j), j * dp[i-j])
        }
    }
    return dp[n]
};

二、不同的二叉搜索树

五部曲

  1. dp[i],表示1到i个节点组成的二叉搜索树的个数
  2. 递推公式, dp[i] += dp[j-1] * dp[i - j], 以j为头节点,左边节点数为j - 1, 右边数为i - j
  3. dp[0] = 1
  4. 遍历顺序
  5. 举例推导
/**
 * @param {number} n
 * @return {number}
 */
var numTrees = function (n) {
    let dp = new Array(n + 1).fill(0)
    dp[0] = 1
    for (let i = 1; i <= n; i++) {
        for (let j = 1; j <= i; j++) {
            dp[i] += dp[j - 1] * dp[i - j]
        }
    }
    return dp[n]
};