题目:
给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
class Solution {
// 贪心算法::其实就是求相邻两天的利润,然后只取正数,也就是局部最优
// 因为连续几天的利润也是相邻两天的利润的总合嘛~~
// 如第0天买入,第3天卖出,那么利润为 prices[3] - prices[0],
// 也就是把利润划分为每天为单位的维度,而不是整体考虑
// prices[3] - prices[0] = (prices[3] - prices[2]) +
// (prices[2] - prices[1]) +
// (prices[1] - prices[0])
public:
// int maxProfit(vector<int>& prices)
// {
// int result = 0;
// for(int i = 1; i < prices.size(); i++)
// {
// if((prices[i] - prices[i-1]) > 0)
// {
// result += prices[i] - prices[i-1];
// }
// }
// return result;
// }
// 法二::动态规划
// 这题就是可以买卖多次
/*
时间复杂度:O(n)
空间复杂度:O(n)
*/
// 写法一:正常的 dp 数组
// int maxProfit(vector<int>& prices)
// {
// // dp[i][0] 第i天 持有股票 的最多现金
// // dp[i][1] 第i天 不持有股票 的最多现金
// int n = prices.size();
// vector<vector<int>> dp(n, vector<int>(2, 0));
// dp[0][0] = - prices[0]; // 持股票
// for(int i = 1; i < n; i++)
// {
// // 只有 dp[i][0] 与只能买一次的逻辑不一样,就是当持有股票,且前一天不持有,今天买入的话
// // 由 dp[i - 1][1] - prices[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 max(dp[n - 1][0], dp[n - 1][1]);
// }
// 写法二:滚动数组写法
/*
时间复杂度:O(n)
空间复杂度:O(1)
*/
int maxProfit(vector<int>& prices)
{
int len = prices.size();
// 滚动数组,为什么设置为 两行呢?
// 因为只需要保留前一天的状态即可,也就是一共就两天的状态,来回滚动嘛
vector<vector<int>> dp(2, vector<int>(2, 0));
dp[0][0] = -prices[0];
for(int i = 1; i < len; ++i)
{
dp[i % 2][0] = max(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1] - prices[i]);
dp[i % 2][1] = max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][0] + prices[i]);
}
return dp[(len - 1) % 2][1];
}
};