买卖股票的最佳时机
- 根据题目,得知只能进行一次交易,即只能买一次、卖一次。有可能长期持有一支低价的股票,等到最后高价时卖掉。
- 定义
buy
为买入股票的收入,sell
为卖出股票的收入,buy+prices[i]
为每日卖出股票的收入。
- 可以得出两个公式:
sell = Math.max(sell,buy+prices[i])
buy = Math.max(buy,-prices[i])
- 具体代码如下
var maxProfit = function(prices) {
var buy = -prices[0],sell = 0;
for(var i = 1;i<prices.length;i++){
sell = Math.max(sell,buy+prices[i]);
buy = Math.max(buy,-prices[i]);
}
return sell;
};
买卖股票的最佳时机 II
- 根据题意,得知可以进行多次交易,所以可以多次买入,多次卖出。
- 所以定义
buy
为买入股票的收入,sell
为卖出股票的最终收入
,buy+prices[i]
为每日卖出股票的收入。
- 可以得出两个公式:
sell = Math.max(sell,buy+prices[i]+sell)
buy = -prices[i]
- 具体代码如下
var maxProfit = function(prices) {
var buy = -prices[0],sell = 0;
for(var i = 1;i<prices.length;i++){
sell = Math.max(sell,buy+prices[i]+sell);
buy = -prices[i];
}
return sell;
};
买卖股票的最佳时机 III
- 根据题意,最多可以完成
两次
交易。每天可能有5
中状态
- 没有进行任何交易
- 买入一支股票
- 完成一次交易
- 完成一次交易,然后买入一支股票
- 完成两次交易
- 上述状态中,
没有进行任何交易
最终的结果是0
,可以忽略这种状态。所以可以定义如下几个变量:
buy1
:买入一支股票
sell1
:完成一次交易
buy2
:完成一次交易,然后买入一支股票
sell2
:完成两次交易
- 如何确定这4个变量的关系
买入一支股票
。假设每天都要买一支股票,即:buy=-prices[i]
。我们需要求最大值,所以需要和上次的买入时做对比,即:buy1 = Math.max(buy1,-prices[i])
。
完成一次交易
。完成一次交易的公式是:sell=buy+prices[i]
。所以:sell1 = Math.max(sell1,buy1+prices[i])
。
完成一次交易,然后买入一支股票
。因为已经完成一次交易,所以再买入一支股票的结果是:buy=sell-prices[i]
。所以:buy2 = Math.max(buy2,sell1-prices[i])
。
完成两次交易
与完成一次交易
类似,所以:sell2 = Math.max(sell2,buy2+prices[i])
。
- 具体代码如下
var maxProfit = function(prices) {
var buy1 = -prices[0],buy2 = -prices[0],sell1 = 0,sell2 = 0;
for(var i = 1;i<prices.length;i++){
buy1 = Math.max(buy1,-prices[i]);
sell1 = Math.max(sell1,buy1+prices[i]);
buy2 = Math.max(buy2,sell1-prices[i]);
sell2 = Math.max(sell2,buy2+prices[i]);
}
return sell2;
};
买卖股票的最佳时机 IV
- 本题和
买卖股票的最佳时机 III
类似,从最多可以完成两次
交易,变成最多可以完成k次
交易。
- 我们对比
买卖股票的最佳时机 III
,2次
交易有4种
状态,所以k次
交易有2*k种
状态。
2*k种
状态是k次
买入,和k次
卖出的集合,可以用j
表示第几次买或卖,即arr[j]=[buy,sell]
。
- 用
price
表示第i
天的价格,buy
和sell
分别表示第j
次的买卖收入,可以得出下面的公式:
j=0
时。arr[0]=[Math.max(buy,-price),Math.max(sell,buy+price)]
j>0
时。第j
次的买的价格,是上一次卖的价格减掉当日的价格;第j
次的卖的收入,是本次卖的收入加上当日的价格。即:arr[j]=[Math.max(buy,arr[j-1][1]-price),Math.max(sell,arr[j][0]+price)]
- 具体代码如下
var maxProfit = function(k, prices) {
var arr = new Array(k);
for(var j = 0;j<k;j++){
arr[j] = [-prices[0],0];
}
for(var i = 1;i<prices.length;i++){
var price = prices[i];
var buy = arr[0][0],sell = arr[0][1];
arr[0] = [Math.max(buy,-price),Math.max(sell,buy+price)];
for(var j = 1;j<k;j++){
buy = arr[j][0],sell = arr[j][1];
arr[j] = [Math.max(buy,arr[j-1][1] - price),Math.max(sell,arr[j][0] + price)];
}
}
return arr[arr.length-1][1];
};
买卖股票的最佳时机含手续费
- 本题比上几题,多了手续费,更符合实际交易的场景🐶
- 因为有手续费,所以有可能存在持有一支股票,等到卖掉时的价钱能够抵掉手续费时才卖掉。
- 假设
sell
是卖掉时的收入,buy
是买入时的收入。
- 当日的
sell
是buy + prices[i] - fee
,当日的buy
是sell-prices[i]
。
- 因为需要求最大值,所以可以得出下面的公式:
sell = Math.max(sell, buy + prices[i] - fee)
buy = Math.max(buy, sell - prices[i])
- 具体代码如下
var maxProfit = function(prices, fee) {
var buy = -prices[0],sell = 0;
for(var i = 1;i<prices.length;i++){
sell = Math.max(sell, buy + prices[i] - fee);
buy = Math.max(buy, sell - prices[i]);
}
return sell;
};
最佳买卖股票时机含冷冻期
- 本题多了冷冻期的概念,即:卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
- 假设
sell
是卖掉时的收入,buy
是买入时的收入,freeze
是冷冻期的收入。
- 在冷冻期是不能进行买卖的,所以冷冻期的收入是前一天的
卖掉
后的收入。
- 冷冻期过后,才能进行买卖,所以每日卖掉的收入是冷冻期的收入减去当日的价格。
- 所以可以得出下面的公式:
sell = Math.max(sell,buy+prices[i])
buy = Math.max(buy,freeze-prices[i])
freeze = 前一天卖掉的收入
- 具体代码如下
var maxProfit = function(prices) {
var sell = 0,buy = -prices[0],freeze = 0;
for(var i = 1;i<prices.length;i++){
var temp = sell;
sell = Math.max(sell,buy+prices[i]);
buy = Math.max(buy,freeze-prices[i]);
freeze = temp;
}
return sell;
};
总结
- 根据
买卖股票
的题目要求,确定各种状态,如果买入时的收入
、卖掉时的收入
等。
- 确定各种状态之间的关系,得出相应的公式。
- 根据公式实现具体的代码。