碎碎念:头好痒 要长脑子了
参考:代码随想录
121. 买卖股票的最佳时机
题目链接
思想
每一天都有两个状态,买这支股票和不买这支股票。注意本题的股票只能买卖一次。
动态规划五部曲:
- 确定dp数组以及下标的含义:dp[i][0],第i天持有股票所能得到的最大金额;dp[i][1],第i天不持有股票所能得到的最大金额。最后比较dp[len-1][0]和dp[len-1][1]。
- 确定递推公式:
- dp数组的初始化:dp[0][0]=-prices[0], dp[0][1]=0
- 确定遍历顺序:for循环,从前往后遍历
- 打印dp数组:主要用来debug。
题解
// cpp
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
if (len == 0) return 0;
vector<vector<int>> dp(len, vector<int>(2));
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i = 1; i < len; 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[len-1][1];
}
};
# python
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if len(prices) == 0:
return 0
dp = [[0] * 2 for _ in range(len(prices))]
dp[0][0] = -prices[0]
dp[0][1] = 0
for i in range(1, len(prices)):
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[-1][1]
反思
122.买卖股票的最佳时机II
题目链接
思想
与上一题的区别在于,本题的股票可以买卖多次。
动态规划五部曲:
- 确定dp数组以及下标的含义:dp[i][0],第i天持有股票所能得到的最大金额;dp[i][1],第i天不持有股票所能得到的最大金额。最后比较dp[len-1][0]和dp[len-1][1]。
- 确定递推公式:
- dp数组的初始化:dp[0][0]=-prices[0], dp[0][1]=0
- 确定遍历顺序:for循环,从前往后遍历
- 打印dp数组:主要用来debug。
题解
// cpp
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
vector<vector<int>> dp(len, vector<int>(2, 0));
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i = 1; i < len; 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[len-1][1];
}
};
# python
class Solution:
def maxProfit(self, prices: List[int]) -> int:
length = len(prices)
if length == 0:
return 0
dp = [[0] * 2 for _ in range(length)]
dp[0][0] = -prices[0]
dp[0][1] = 0
for i in range(1, length):
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[-1][1]
反思
注意和上一题对比。
123.买卖股票的最佳时机III
题目链接
思想
本题的股票至多买卖两次。
动态规划五部曲:
-
确定dp数组以及下标的含义:dp[i][0],不操作;dp[i][1],第一次持有;dp[i][2]第i天不持有;dp[i][3]第二次持有;dp[i][4]第二次不持有。最后返回dp[len-1][4]
-
确定递推公式:
-
dp数组的初始化:dp[0][0]=0, dp[0][1]=-prices[0],dp[0][2]=-prices[0],dp[0][3]=0,dp[0][4]=0
-
确定遍历顺序:for循环,从前往后遍历
-
打印dp数组:主要用来debug。
题解
// cpp
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
if (len == 0) return 0;
vector<vector<int>> dp(len, vector<int>(5, 0));
dp[0][1] = -prices[0];
dp[0][3] = -prices[0];
for (int i = 1; i < len; i++) {
dp[i][0] = dp[i - 1][0];
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);
dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
}
return dp[len-1][4];
}
};
# python
class Solution:
def maxProfit(self, prices: List[int]) -> int:
length = len(prices)
if length == 0:
return 0
dp = [[0] * 5 for _ in range(length)]
dp[0][1] = -prices[0]
dp[0][3] = -prices[0]
for i in range(1, length):
dp[i][0] = dp[i-1][0]
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
dp[i][2] = max(dp[i-1][2], dp[i-1][1] + prices[i])
dp[i][3] = max(dp[i-1][3], dp[i-1][2] - prices[i])
dp[i][4] = max(dp[i-1][4], dp[i-1][3] + prices[i])
return dp[-1][4]