Leetcode個人題解714
阿新 • • 發佈:2019-02-20
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)