1

微信图片_20200526141455.png
微信图片_20200526141513.png

这两题的共同点就是状态只有日期(只有 i 的变化才会导致结果的变化),即数组索引 i

做这类题其实只要能写出 dfs 解法,然后在其基础上优化,最后一定能通过测试。

为什么建议先写 dfs 呢?因为 dfs 解法更符合我们的思维方式,更容易写出题解。

找到了状态 i,就是找到了 dfs 函数的参数,即:

function dfs(i){
}

每一个 dfs(i)中都有两个状态值:有股票状态和没有股票状态的钱。
所以函数的返回值为:

function dfs(i){
    return [当前没股票的钱,当前有股票的钱]
}

309. 最佳买卖股票时机含冷冻期 题解:

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(prices) {

    function dfs(i){
        // 边界
        if(i < 0) return [0,Number.MIN_SAFE_INTEGER]
        // 当前没有股票状态为:
        // 前一天没有股票和前一天没有股票今天卖出,两者中的最优值
        // 当前有股票状态为:
        // 前一天没有股票和前2天没有股票今天买入,两者中的最优值
        const status_0 = Math.max(dfs(i-1)[0],dfs(i-1)[1]+prices[i])
        const status_1 = Math.max(dfs(i-1)[1],dfs(i-2)[0]-prices[i])
        return [status_0,status_1]
    }
    return dfs(prices.length-1)[0]
    
 -----------------------分界线----------------------------

    // 优化:
    // 通过 dfs 函数可以知道,其实只需要保存前两天的状态
    // 因为 dfs(i) 只与 dfs(i-1) 和 dfs(i-2)有关
    // 使用自底向上的动态规划,对暴力 dfs 进行优化
    let prev_1 = [0,Number.MIN_SAFE_INTEGER], prev_2 = [0,Number.MIN_SAFE_INTEGER]
    for(let i = 0, len = prices.length; i<len; i++){
        const status_0 = Math.max(prev_1[0],prev_1[1]+prices[i])
        const status_1 = Math.max(prev_1[1],prev_2[0]-prices[i])
        prev_2 = prev_1
        prev_1 = [status_0,status_1]
    }
    return prev_1[0]
    
};

714. 买卖股票的最佳时机含手续费 题解:

/**
 * @param {number[]} prices
 * @param {number} fee
 * @return {number}
 */
var maxProfit = function(prices, fee) {

    function dfs(i){
        // 边界值
        if(i < 0) return [0,Number.MIN_SAFE_INTEGER]
        // 当前没有股票为:
        // 前一天没有股票和前一天没有股票今天卖出再减去手续费,两者中的最优值
        // 当前有股票为:
        // 前一天没有股票和前一天没有股票今天买入,两者中的最优值
        const status_0 = Math.max(dfs(i-1)[0],dfs(i-1)[1]+prices[i]-fee)
        const status_1 = Math.max(dfs(i-1)[1],dfs(i-1)[0]-prices[i])
        return [status_0,status_1]
    }
    return dfs(prices.length-1)[0]

    
 -----------------------分界线----------------------------

    // 优化:
    // 通过 dfs 函数可以知道,其实只需要保存前一天的状态
    // 因为 dfs(i) 只与 dfs(i-1)有关
    // 使用自底向上的动态规划,对暴力 dfs 进行优化
    let prev = [0,Number.MIN_SAFE_INTEGER]
    for(let i = 0, len = prices.length; i<len; i++){
        const status_0 = Math.max(prev[0],prev[1]+prices[i]-fee)
        const status_1 = Math.max(prev[1],prev[0]-prices[i])
        prev = [status_0,status_1]
    }
    return prev[0]
    
};

TENG
11 声望0 粉丝