leetcode 30九、714股票問題含手續費和冷凍期,DFS模板解法

微信圖片_20200526141455.png
微信圖片_20200526141513.png

這兩題的共同點就是狀態只有日期(只有 i 的變化纔會致使結果的變化),即數組索引 i數組

作這類題其實只要能寫出 dfs 解法,而後在其基礎上優化,最後必定能經過測試。微信

爲何建議先寫 dfs 呢?由於 dfs 解法更符合咱們的思惟方式,更容易寫出題解。函數

找到了狀態 i,就是找到了 dfs 函數的參數,即:測試

function dfs(i){
}

每個 dfs(i)中都有兩個狀態值:有股票狀態和沒有股票狀態的錢。
因此函數的返回值爲:優化

function dfs(i){
    return [當前沒股票的錢,當前有股票的錢]
}

309. 最佳買賣股票時機含冷凍期 題解:spa

/**
 * @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. 買賣股票的最佳時機含手續費 題解:code

/**
 * @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]
    
};
相關文章
相關標籤/搜索