這兩題的共同點就是狀態只有日期(只有 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] };