Skip to content

动态规划

重要点:

  • 寻找状态转移方程
  • 建立合适的数据结构表(多为类数组结构)
  • 返回符合题意的结果

爬楼梯

经典问题

js
function climbStairs (n) {
    let dp1 = 0, dp2 = 1, res = 1
    for(let i = 1; i < n; i++) {
        dp1 = dp2
        dp2 = res
        res = dp1 + dp2
    }
    return res
}

打家劫舍

状态转换方程 dp[n] = Max(dp[n-1], dp[n-2] + nums[n])

js
var rob = function(nums) {
    const len = nums.length;
    if (len === 0) {
        return 0;
    }
    const dp = new Array(len + 1);
    dp[0] = 0;
    dp[1] = nums[0];
    for (let i = 2; i <= len; i++) {
        dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]);
    }
    return dp[len];
};

最大子数和

js
var maxSubArray = function(nums) {
    let pre = 0, maxAns = nums[0];
    for (let i = 0; i < nums; i++) {
        pre = Math.max(pre + x, x);
        maxAns = Math.max(maxAns, pre);
    }
    return maxAns;
};

零钱兑换

js
var coinChange = function(coins, amount) {
    const dp = new Array(amount + 1).fill(amount + 1)
    dp[0] = 0
    for (let i = 1; i <= amount; i++) {
        for (let j = 0; j < coins.length; j++) {
            // 如果以 coins[j]为步长,前面不存在台阶,继续下一次(如果步长有序,则可 break
            if (i < coins[j]) continue
            dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1)
        }
    }
    return dp[amount] > amount ? -1 : dp[amount]
};

最长递增子序列

js
var lengthOfLIS = function(nums) {
    if (nums.length <= 1) {
        return nums.length;
    }
    let n = nums.length;
    let maxLength = 0;
    let dp = [];
    dp[0] = 1;
    for (let i = 1; i < n; i++) {
        let max = 0;
        for (let j = i - 1; j >= 0; j--) {
            if (nums[j] < nums[i]) {
                max = Math.max(dp[j], max);
            }
        }
        dp[i] = max + 1;
        maxLength = Math.max(maxLength, dp[i]);
    }
    return maxLength;
};

零钱兑换

js
var coinChange = function(coins, amount) {
    const maxCount = amount + 1;
    const dp = new Array(maxCount).fill(maxCount);
    dp[0] = 0;
    for (let i = 1; i <= amount; i++) {
        for (let j = 0; j < coins.length; j++) {
            if (coins[j] <= i) {
                dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
            }
        }
    }
    return dp[amount] > amount ? -1 : dp[amount]
};

最长回文子串

TODO

最大正方形

TODO

Released under the MIT License.