题意:
给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。
你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。
返回获得利润的最大值。
注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。
// /*
// 这题贪心有点难想的到,就怎么处理计算利润,已经如何更新 minPrice很饶。
// 贪心思想:最低值买,最高值(最高值需要减去买入值和手续费)就卖
// */
// // 时间复杂度 O(n) 空间复杂度 O(1)
// class Solution {
// public:
// int maxProfit(vector<int>& prices, int fee)
// {
// int result = 0;
// int minPrice = prices[0];
// for(int i = 1; i < prices.size(); i++)
// {
// // 情况二: 相当于买入
// if(prices[i] < minPrice)
// {
// minPrice = prices[i];
// }
// // 计算利润,这里有可能计算多次,但最后一次计算利润才是真正意义的卖出
// if(prices[i] > minPrice + fee)
// {
// result += prices[i] - minPrice - fee;
// minPrice = prices[i] - fee; // 情况一:
// // 这里不知道为什么????
// // 啊!~好像知道了,这样确实是把 minPrice 改变了,但是也只有第 i 天之后出现的股票价格 大于 prices[i] - fee,才有可能被用上,否则,第i天就需要卖股票咯~而且这样不会导致在第 i 天后出现更高的股票价格后,result多见一个 fee
// }
// // 其实情况三:就可以理解为 else 的情况。不做操作就相当于 进入下一轮循环
// }
// return result;
// }
// };
// /************************法二: 动态规划**************************/
/* 时间复杂度 O(n) 空间复杂度 O(n)
本题中 与多次买卖股票非常类似,只需要在计算卖出操作时,减去手续费即可。
*/
// class Solution {
// public:
// int maxProfit(vector<int>& prices, int fee)
// {
// // dp[i][0] 第 i 天持有股票所剩的最多现金
// // dp[i][1] 第 i 天不持有股票所剩的最多现金
// int n = prices.size();
// vector<vector<int>> dp(n,vector<int>(2,0));
// dp[0][0] = dp[0][0] - prices[0]; // 持股票
// for(int i = 1; i < n; 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] - fee);
// }
// return max(dp[n - 1][0], dp[n - 1][1]);
// }
// };
/************************法三: 优化了空间的动态规划**************************/
// 时间复杂度 O(n) 空间复杂度 O(1)
// 相当于使用了滚动数组的形式
class Solution {
public:
int maxProfit(vector<int>& prices, int fee)
{
int n = prices.size();
int holdStock = (-1) * prices[0]; // 持股票
int saleStock = 0; // 卖出股票
for(int i = 1; i < n; i++)
{
int previousHoldStock = holdStock;
holdStock = max(holdStock, saleStock - prices[i]);
saleStock = max(saleStock, previousHoldStock + prices[i] - fee);
}
return saleStock;
}
};