LEETCODE专题
714. Best Time to Buy and Sell Stock with Transaction Fee
题目要求:
这里题目要求我们选择最好的时间买卖股票以赚取最高的利润($_$),当然这是非常简化的版本。在题目里给出了每一天的股票金额,我们买入的时候就需要支付这些金额,卖出的时候就可以得到这些股票金额减去交易费fee的差价,当然,我们也可以选择不买也不卖,有时候股票行情不好的时候不买也不卖是最明智的行为(^_^)。
问题:
- 这个问题的子问题,很明显是一个前缀问题。也就是后面的操作实际上是取决于前缀的,后面能够赚到的最大利润也是根据前面的选择来定的。但是,在操作的时候,我们会遇到这样一个问题,如何决定今天的操作?
有时候我们需要将买入的股票一直持有到股票金额适当高的时候抛出,那么我们如何持有股票?比如我们考虑下列两种输入
1. 输入:[1, 3, 2, 8] 最大利润: (8 - 1) - 2 = 5 2. 输入:[1, 7, 2, 8] 最大利润:( (7 - 1) - 2) + ( (8 - 2) - 2) = 8 第一种情况就有必要将第一天买入的股票持有到第四天。
分析:
- 关于第一个问题,笔者使用了一个只有三个元素的数组,分别代表3个操作所造成的今天的最大利润结果。那么明天的操作结果,就可以根据今天所得到的最大利润结果来得到。
- 对于第二个问题,笔者使用了判断来决定今天是否买入股票,如果不买入股票,有两种可能,第一种是目前不持有股票,第二种是已买入股票,那么我们就可以将已买入股票所造成的最大利润结果存入事先建好的数组对应位置中。
举例来说
输入:[1, 3, 2, 8, 4, 9]
操作:
operation \ money of day | 1 | 3 | 2 | 8 | 4 | 9 |
---|---|---|---|---|---|---|
have bought or bought | -1 | -1 | 2 | 2 | 4 | -1 |
sold | 0 | 4 | -1 | 8 | 4 | 11 |
neither | 0 | 0 | 4 | 4 | 8 | 8 |
最大利润结果:11
这里笔者假定初始持有金额为0,第一天买入股票后持有金额为0 - 今日股票金额,第一天卖出股票后持有金额初始化为0,不买也不卖后持有金额为0。假如第一天我们没有买入股票,那么到了第二天我们就可以买入股票,但是此时持有金额会比第一天买入股票后持有金额少,所以我们选择第一天买股票,持有金额也就是-1而非-3。第三天我们买入了股票,所以持有金额为第二天不买入股票的最大利润结果(可以将sold和neither比较一下得到)减去今日股票金额得到。
但是这里要记得卖出股票时我们还要减去交易费fee。
下面直接上代码:
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
/*
* Firstly, we initial an 2-dimension array
* the first dimension stores the index of
* the vector of prices, the second dimension
* includes a fixed space of 3, each having
* its own meaning:
* 1. the max profit of having bought a stock.
* the stock can be bought earlier
* 2. the max profit of selling a stock today
* 3. the max profit of neither buying nor
* selling a stock
*
* The 2-dimension array can be used to get
* the max profit at the last day, which can
* be achieved by selling a stock or neither
* buying nor selling a stock.
*
* Maybe you want to ask why it can't be got
* by buying a stock.
* This is because if you do nothing at the
* last day, you can make more money than
* buying a stock.
*/
if (prices.size() == 1) return 0;
int size_of_prices = prices.size();
int ** states = new int *[size_of_prices];
int i;
for (i = 0; i < size_of_prices; i++) {
states[i] = new int[3];
}
// initial the first value of the 2-d array
states[0][0] = 0 - prices[0];
states[0][1] = 0;
states[0][2] = 0;
// get the max profit
for (i = 1; i < size_of_prices; i++) {
int s0 = states[i - 1][0];
int s1 = states[i - 1][1];
int s2 = states[i - 1][2];
// get the first argument
int b1 = s1 - prices[i];
int b2 = s2 - prices[i];
int buy = b1 > b2 ? b1 : b2;
states[i][0] = buy > s0 ? buy : s0;
// get the second argument
states[i][1] = prices[i] + s0 - fee;
// get the third argument
states[i][2] = s1 > s2 ? s1 : s2;
}
int s1 = states[i - 1][1];
int s2 = states[i - 1][2];
int max = s1 > s2 ? s1 : s2;
// free the space
for (i = 0; i < size_of_prices; i++) {
delete [] states[i];
}
delete [] states;
return max;
}
};
时间复杂度:O(n)