买卖股票的最佳时机
买卖股票的最佳时机(动态规划)
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。
注意:你不能在买入股票前卖出股票。
来源:力扣(LeetCode)https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock
/**
【动态规划】
前i天的最大收益 = max{前i-1天的最大收益, 第i天的价格 - 前i-1天中的最低价格}
**/
int maxProfit(vector<int>& prices) {
int days = prices.size();
if(days < 2)
return 0;
int pre_min = prices[0]; // 前 i-1 天中的最低价格
int max_earn = 0; // 前 i-1 天的最大收益
for(int i = 1; i < days; ++i){
max_earn = max(max_earn, prices[i] - pre_min);
pre_min = min(pre_min, prices[i]);
}
return max_earn;
}
买卖股票的最佳时机 II(贪心)
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
来源:力扣(LeetCode) https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii
/** 【贪心】
// 遇到低价(比前后都低)便买入
// 遇到高价比前后都高)就卖出
// 持有时间必然是价格上升时间段 才有最大利益
// \ /
// \ /\ /
// \/ \ /
// \/
**/
int maxProfit(vector<int>& prices) {
int sum = 0;
for(int i = 1; i < prices.size(); ++i){
if(prices[i] > prices[i-1])
sum += prices[i] - prices[i-1];
}
return sum;
}
买卖股票的最佳时机 III(动态规划)
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
来源:力扣(LeetCode)https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii
/**
【动态规划】
第i天结束时的可能状态:
1、无买卖操作 0
2、第一次买入 buy_first
3、第一次买卖交易完成 sell_first
4、第二次买入 buy_second
5、第二次交易完成 sell_second
**/
int maxProfit(vector<int>& prices) {
int days = prices.size();
if(days <= 1) return 0;
int buy_first = -prices[0], sell_first = 0;
int buy_second = -prices[0], sell_second = 0;
for(int i = 1; i < days; ++i){
sell_second = max(sell_second, prices[i] + buy_second);
buy_second = max(buy_second, sell_first - prices[i]);
sell_first = max(sell_first, buy_first + prices[i]);
buy_first = max(buy_first, -prices[i]);
}
return max(sell_first, sell_second);
}
买卖股票的最佳时机 IV(动态规划)
给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
来源:力扣(LeetCode)https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv
/**
【动态规划】
第i天结束时的可能状态:
1、无买卖操作 0
2、第j次买入股票 buy[j] 0 < j <= k
3、第j次卖出股票 sell[j] 0 < j <= k
**/
int maxProfit(int k, vector<int>& prices) {
int days = prices.size();
if(k < 1 || days <= 1)
return 0;
vector<int> buy(k, -prices[0]); // buy[j] 第j次买入股票后的收益
vector<int> sell(k, 0); // sell[j] 第j次卖出股票后的收益
for(int i = 1; i < days; ++i){
for(int j = k - 1; j > 0; --j){
sell[j] = max(sell[j], buy[j] + prices[i]);
buy[j] = max(buy[j], sell[j-1] - prices[i]);
}
sell[0] = max(sell[0], buy[0] + prices[i]);
buy[0] = max(buy[0], -prices[i]);
}
int max_earn = 0;
for(auto& val : sell){
if(max_earn < val)
max_earn = val;
}
return max_earn;
}
买卖股票的最佳时机含手续费(动态规划)
给定一个整数数组 prices,其中第 i 个元素代表了第 i 天的股票价格 ;非负整数 fee 代表了交易股票的手续费用。
你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。
返回获得利润的最大值。
注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。
来源:力扣(LeetCode)https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee
/**
【动态规划】
第i天结束时的可能状态:
1、持有股票 hold
2、售出股票 sellout
* 最后一天不持有股票的利润肯定更大
**/
int maxProfit(vector<int>& prices, int fee) {
int days = prices.size();
if(days <= 1)
return 0;
int hold = -prices[0]; // 持有股票
int sellout = 0; // 售出股票 不持有
for(int i = 1; i < days; ++i){
int tmp_hold = max(hold, sellout - prices[i]);
sellout = max(sellout, hold + prices[i] - fee);
hold = tmp_hold;
}
return sellout; // 最后一天不持有股票利润肯定更大
}
最佳买卖股票时机含冷冻期(动态规划)
给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。来源:力扣(LeetCode)https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-cooldown
/**
【动态规划】
第i天结束时的可能状态:
1、持有股票 hold
2、售出股票 sell
3、冷静期 cool
* 最后一天不持有股票的利润肯定更大
**/
int maxProfit(vector<int>& prices) {
int days = prices.size();
if(days <= 1)
return 0;
int hold = -prices[0]; // 持有
int sell = 0; // 售出
int cool = 0; // 冷静期
for(int i = 1; i < days; ++i){
int tmp_sell = max(sell, hold + prices[i]);
int tmp_hold = max(hold, cool -prices[i]);
cool = max(cool, sell);
sell = tmp_sell;
hold = tmp_hold;
}
return sell;
}