Leetcode個人題解714

LEETCODE專題


714. Best Time to Buy and Sell Stock with Transaction Fee

題目要求:
這裏寫圖片描述

這裏題目要求我們選擇最好的時間買賣股票以賺取最高的利潤($_$),當然這是非常簡化的版本。在題目裏給出了每一天的股票金額,我們買入的時候就需要支付這些金額,賣出的時候就可以得到這些股票金額減去交易費fee的差價,當然,我們也可以選擇不買也不賣,有時候股票行情不好的時候不買也不賣是最明智的行爲(^_^)。

問題:

  1. 這個問題的子問題,很明顯是一個前綴問題。也就是後面的操作實際上是取決於前綴的,後面能夠賺到的最大利潤也是根據前面的選擇來定的。但是,在操作的時候,我們會遇到這樣一個問題,如何決定今天的操作?
  2. 有時候我們需要將買入的股票一直持有到股票金額適當高的時候拋出,那麼我們如何持有股票?比如我們考慮下列兩種輸入

    1.
    輸入:[1, 3, 2, 8]
    最大利潤: (8 - 1) - 2 = 5
    
    2.
    輸入:[1, 7, 2, 8]
    最大利潤:( (7 - 1) - 2) + ( (8 - 2) - 2) = 8
    
    第一種情況就有必要將第一天買入的股票持有到第四天。
    

分析:

  1. 關於第一個問題,筆者使用了一個只有三個元素的數組,分別代表3個操作所造成的今天的最大利潤結果。那麼明天的操作結果,就可以根據今天所得到的最大利潤結果來得到。
  2. 對於第二個問題,筆者使用了判斷來決定今天是否買入股票,如果不買入股票,有兩種可能,第一種是目前不持有股票,第二種是已買入股票,那麼我們就可以將已買入股票所造成的最大利潤結果存入事先建好的數組對應位置中。

舉例來說
輸入:[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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章