日常刷题0x10之德玛蹲草丛

184 阅读1分钟

此阶段给自己定的目标是:做过的这些题每天坚持继续刷二遍,每道题做过之后开始尝试多解法尝试解题。上一阶段是感知都有什么题目,此阶段主要系统化常规题解套路知识,牢记牢记此阶段目的。

题号:322
var coinChange = function (coins, amount) {

    if (amount == 0) {
        return 0
    }
    //最大值填充数组方便下面min的比较
    let dptable = new Array(amount + 1).fill(Number.MAX_VALUE)

    for (let i = 0; i < dptable.length; i++) {

        //现阶段决策挑选硬币
        for (let j = 0; j < coins.length; j++) {
            let coin = coins[j]
            if (i - coin == 0) {
                //刚好一个硬币能满足所求就直接为1了
                dptable[i] = 1
                break
            } else if (i - coin > 0) {
                dptable[i] = Math.min(dptable[i - coin] + 1, dptable[i])
            } else {
                //当前选择的硬币大于amount就不满足题意了跳过该选择
                continue
            }
        }
    }
    return dptable[dptable.length - 1] == Number.MAX_VALUE ? -1 : dptable[dptable.length - 1]
};
题号:518
//完全背包
//观察发现一些变量因子,这些变量因子就是我们在每一阶段做决策要依据的因素
//动态规划思考的时候要从上到下的角度,状态转移方程编写是从下到上
var change = function (amount, coins) {

    //dptable 含义:从前i个硬币中选择一些硬币是的额度为j的组合
    let dptable = new Array(coins.length + 1)
    for (let i = 0; i < dptable.length; i++) {
        let arr = new Array(amount + 1)
        dptable[i] = arr
    }
    for (let i = 0; i < dptable.length; i++) {
        for (let j = 0; j < dptable[0].length; j++) {
            if (i == 0) {
                //i==0 0个硬币凑指定金额
                if (j == 0) {
                    //0个硬币凑0金额组合为1
                    dptable[i][j] = 1
                } else {
                    //0个硬币凑不为0的金额组合永远不可能
                    dptable[i][j] = 0
                }
            } else {
                //i!=0的情况下
                //从前i个硬币中选,凑够金额为j
                //站在这个点上的决策是:当前的第i个硬币我不用,那么我从第i-1个硬币中找到满足
                //金额为j的的数量和我选第i个硬币的前提下满足j - coins[i - 1]的金额的组合(可能没有)
                if (j - coins[i - 1] >= 0) {
                    dptable[i][j] = dptable[i - 1][j] + dptable[i][j - coins[i - 1]]
                } else {
                    dptable[i][j] = dptable[i - 1][j]
                }
            }
        }
    }
    return dptable[dptable.length - 1][dptable[0].length - 1]
};
题号:300
var lengthOfLIS = function (nums) {
    if (nums.length == 1) {
        return 1
    }
    //dptable :以元素i结尾的最大所求值
    let dptable = new Array(nums.length).fill(0)

    let result = 0
    for (let i = 0; i < nums.length; i++) {
        if (i == 0) {
            dptable[i] = 1
        } else {
            dptable[i] = 1
            for (let j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dptable[i] = Math.max(dptable[i], dptable[j] + 1)
                }
            }
            result = Math.max(result, dptable[i])
        }
    };
    return result
}