Best Time to Buy and Sell Stock 四连题解
目录
LeetCode 121. Best Time to Buy and Sell Stock I
LeetCode 122. Best Time to Buy and Sell Stock II
LeetCode 123. Best Time to Buy and Sell Stock III
LeetCode 188. Best Time to Buy and Sell Stock IV
LeetCode 121. Best Time to Buy and Sell Stock I
题目描述
假设你有一个数组,其中第 i 个元素表示第 i 天某个股票的价格。
注意:设计一种算法以找到最大利润,你只可以完成1次交易,但必须先购买股票再出售股票
样例
输入: [7,1,5,3,6,4]
输出: 5
解释: 第二天买(price = 1),第五天卖(price=6),利润为5;
输入: [7,6,4,3,1]
输出: 0
解释: 这个例子中没有完成交易。
算法
这道题要求是只能交易一次,因此就是寻找数组内正向的最大差值,解法是维护一个min变量存储当前遇到的最低股价,维护一个max存储当前可能的最大利润(用当前股价减去min),一次顺序遍历数组后max即为结果
代码
int maxProfit(vector<int>& prices) {
int size=prices.size(), res=0, minPrice=INT_MAX;
for(int i=0;i<size;i++){
minPrice=min(minPrice,prices[i]);
res=max(res,prices[i]-minPrice);
}
return res;
}
LeetCode 122. Best Time to Buy and Sell Stock II
题目描述
假设你有一个数组,其中第 i 个元素表示第 i 天某个股票的价格。
注意:设计一种算法以找到最大利润,可以完成任意多次交易,但必须先购买股票再出售股票,不能同时多次交易。
样例
输入: [7,1,5,3,6,4]
输出: 7
解释: 第二天买(price = 1),第三天卖(price=5),利润为4;
第四天买(price = 3),第五天卖(price=6),利润为3。
输入: [1,2,3,4,5]
输出: 4
解释: 第一天买(price = 1),第五天卖(price=5),利润为4。
输入: [7,6,4,3,1]
输出: 0
解释: 这个例子中没有完成交易。
算法
这道题要求是可以进行多次交易,利用贪心就可以了,每次股价比昨天贵就加上这个差值。
代码
int maxProfit(vector<int>& prices) {
int total = 0;
for (int i=0; i<(int)prices.size()-1; i++) {
if (prices[i+1]>prices[i])
total += prices[i+1]-prices[i];
}
return total;
}
LeetCode 123. Best Time to Buy and Sell Stock III
题目描述
假设你有一个数组,其中第 i 个元素表示第 i 天某个股票的价格。
注意:设计一种算法以找到最大利润,你最多可以完成2次交易,但必须先购买股票再出售股票,不能同时多次交易。
样例
输入: [3,3,5,0,0,3,1,4]
输出: 6
解释: 第四天买(price = 0),第六天卖(price=3),利润为3;
第七天买(price = 1),第八天卖(price=4),利润为3。
输入: [1,2,3,4,5]
输出: 4
解释: 第一天买(price = 1),第五天卖(price=5),利润为4。
输入: [7,6,4,3,1]
输出: 0
解释: 这个例子中没有完成交易。
算法
这道题要求是可以进行两次交易,我们维护两种量,一个是当前到达第i天可以最多进行j次交易,最好的利润是多少(global[i][j]),另一个是当前到达第i天,最多可进行j次交易,并且最后一次交易在当天卖出的最好的利润是多少(local[i][j])。两个数组的递推公式如下:
代码
int maxProfit(vector<int>& prices) {
if(prices.size()==0)
return 0;
int local[3] = {0};
int global[3] = {0};
//say there are 5 days, i iterates to 3(not 4). After every iteration of i, global[] return the profit up to (i+1)th days.
for(int i=0;i<prices.size()-1;i++)
{
int diff = prices[i+1]-prices[i];
for(int j=2;j>=1;j--)
{
local[j] = max(global[j-1]+(diff>0?diff:0), local[j]+diff);
global[j] = max(local[j],global[j]);
}
}
return global[2];
}
LeetCode 188. Best Time to Buy and Sell Stock IV
题目描述
假设你有一个数组,其中第 i 个元素表示第 i 天某个股票的价格。
注意:设计一种算法以找到最大利润,你最多可以完成K次交易,但必须先购买股票再出售股票,不能同时多次交易。
样例
输入: [2,4,1], k = 2
输出: 2
解释: 第一天买(price = 2),第二天卖(price=4),利润为2;
输入: [3,2,6,5,0,3], k = 2
输出: 7
解释: 第二天买(price = 2),第三天卖(price=6),利润为4。
第五天买(price = 0),第六天卖(price=3),利润为3。
算法
这道题与上题类似,将2次扩充到K次,用动态规划求解
代码
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
int len = prices.size();
if(len == 0){
return 0;
}else if (len/2 < k){
return quickSolve(prices);
}
vector<int> buy(k+1,INT_MIN);//第k次交易买入的最大收益;
vector<int> sell(k+1,0);//第k次交易卖出的最大收益;
for (int i=0;i<len;i++){
for (int j=1;j<=k;j++){
buy[j] = max(buy[j],sell[j-1]-prices[i]);
sell[j] = max(sell[j],buy[j]+prices[i]);
}
}
return sell[k];
}
int quickSolve(vector<int>& prices) {
int len = prices.size(), profit = 0;
for (int i = 1; i < len; i++)
// as long as there is a price gap, we gain a profit.
if (prices[i] > prices[i - 1]) profit += prices[i] - prices[i - 1];
return profit;
}
};
来源:CSDN
作者:YQ_Cheng
链接:https://blog.csdn.net/qq_41685265/article/details/104355617