目录
讀題
121. 买卖股票的最佳时机
自己看到题目的第一想法
這題有做過,當初的想法就是遍歷所有數,假設min > 當前數值,代表有數值更低,更新min,假設沒有則看當前數值-min 是否有大於max_profile更新MAX_profile,但感覺跟動態規劃有點差異。
看完代码随想录之后的想法
我之前的想法在這題當中是貪心算法的思路,看到解題思路,感覺有點奇妙,感覺又有點像是貪心算法,可是卻是以一種動態規劃的形式去推導, 讓整體的流程很清晰容易理解。
122.买卖股票的最佳时机II
自己看到题目的第一想法
之前自己的做法比較偏向是貪心算法,如果要換成動態規劃,則會有點不知道到底要怎麼定義下標,有想到可能可以跟121類似只是要改成[0] 是當前profile [1]是之前累積的profile,但我要跟之前的比較,這就有點犯難了
看完代码随想录之后的想法
看完之後,發現只要將因為賣出就會得到利潤,透過改變當前手上持有的現金,去轉換遞推公式,就可以解決這個問題了。
121. 买卖股票的最佳时机 - 實作
思路
-
定義DP數組以及下標的含意
分為兩種狀況
dp[i][0] 第i天持有股票的現金
dp[i][1] 第i天不持有股票所得的現金
-
遞推公式
dp[i][0]
分兩種狀況
- 第i - 1天持有股票的狀況 dp[i - 1][0]
- 第i天持有股票的狀況 -price[i]
我們要瞭解到dp[i][0] 主要是比較昨天持有比較值得還是今天持有該股票會比較值得
dp[i][0] = max(dp[i - 1][0], -price[i])
也是分兩種狀況
- 第i - 1天不持有股票所可以得到的最大金額
- 第i天不持有股票所可以得到的最大金額
dp[i][1] 可以思考為昨天之前賣掉股票會比較多錢還是今天賣股票會比較多錢
dp[i][1] = max(dp[i - 1][0], price[i] + dp[i - 1][0])
-
根據遞推公式、題意以及定義,確定DP數組如何初始化
dp[0][0] 代表第一天持有股票 所以是-price[0]
dp[0][1] 代表第一天還沒有賣出股票所以是 0
-
確定遍歷順序
是透過前面的狀況推導出後面的狀況,所以是由前往後遍歷
Code
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<vector<int>> dp (prices.size(), vector<int>(2));
dp[0][0] = -prices[0];
dp[0][1] = 0;
for(int i = 1; i < prices.size(); i++) {
dp[i][0] = max(dp[i - 1][0], -prices[i]);
dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);
}
return dp[prices.size() - 1][1];
}
};
122.买卖股票的最佳时机II - 實作
思路
-
定義DP數組以及下標的含意
分為兩種狀況
dp[i][0] 第i天持有股票的現金
dp[i][1] 第i天不持有股票所得的現金
-
遞推公式
dp[i][0]
分兩種狀況
- 第i - 1天持有股票的狀況 dp[i - 1][0]
- 第i天持有股票的狀況,那就必須把目前的股票賣出買入新的股票,也就是dp[i - 1][1] -price[i],dp[i - 1] 代表前一天所得到的利潤
我們要瞭解到dp[i][0] 主要是比較昨天持有比較值得還是今天持有該股票會比較值得
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] -price[i] )
也是分兩種狀況
- 第i - 1天不持有股票所可以得到的最大金額
- 第i天不持有股票所可以得到的最大金額
dp[i][1] 可以思考為昨天之前賣掉股票會比較多錢還是今天賣股票會比較多錢
dp[i][1] = max(dp[i - 1][0], price[i] + dp[i - 1][0])
-
根據遞推公式、題意以及定義,確定DP數組如何初始化
dp[0][0] 代表第一天持有股票 所以是-price[0]
dp[0][1] 代表第一天還沒有賣出股票所以是 0
-
確定遍歷順序
是透過前面的狀況推導出後面的狀況,所以是由前往後遍歷
Code
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<vector<int>> dp (prices.size(), vector<int>(2));
dp[0][0] = -prices[0];
dp[0][1] = 0;
for(int i = 1; i < prices.size(); i++) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
}
return dp[prices.size() - 1][1];
}
};
總結
自己实现过程中遇到哪些困难
今天的兩個問題主要南點是在如何想像動態規劃去解決這兩個問題
並且在第二題問題當中,如何透過第一個問題,轉化思路調整遞推公式,去使得公式與貪心算法其實會很相似
今日收获,记录一下自己的学习时长
今天大概學了1.5hr,主要是理解之前提交過的算法,如何用更清晰的方式,轉換為動態規劃。
相關資料
● 今日学习的文章链接和视频链接
121. 买卖股票的最佳时机
视频讲解:动态规划之 LeetCode:121.买卖股票的最佳时机1_哔哩哔哩_bilibili
https://programmercarl.com/0121.买卖股票的最佳时机.html
122.买卖股票的最佳时机II
视频讲解:动态规划,股票问题第二弹 | LeetCode:122.买卖股票的最佳时机II_哔哩哔哩_bilibili
https://programmercarl.com/0122.买卖股票的最佳时机II(动态规划).html