買賣股票系列

121. Best Time to Buy and Sell Stock
122. Best Time to Buy and Sell Stock II
123. Best Time to Buy and Sell Stock III
188. Best Time to Buy and Sell Stock IV
309. Best Time to Buy and Sell Stock with Cooldown
714. Best Time to Buy and Sell Stock with Transaction Fee

這類問題的總結

  • 在某一天如果不賣股票,利益就是前一天的利益
  • 如果賣股票悴能,要知道之前最低的成本是多少

121. Best Time to Buy and Sell Stock

class Solution {
    //之前我們用O(n^2)的方法求一個價格后的最大價格
    //轉換思路
    //維持某價格前的最小價格
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length == 0) return 0;
        int minPrice = prices[0];
        int maxProfit = 0;
        for (int i = 1; i < prices.length; i++) {
            //current price - previous minimum price, compare to the maxProfit
            maxProfit = Math.max(maxProfit, prices[i] - minPrice);
            //update minPrice
            minPrice = Math.min(minPrice, prices[i]);
        }
        return maxProfit;
    }
}

122. Best Time to Buy and Sell Stock II

  • 可以有多次交易
  • 只要交易能賺錢(今天的價格比昨天的價格高)揣钦,就交易
class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length == 0) return 0;
        int res = 0;
        for (int i = 1; i < prices.length; i++) {
            if (prices[i] > prices[i-1]) {
                res += prices[i] - prices[i-1];
            }
        }
        return res;
    }
}

123. Best Time to Buy and Sell Stock III

step by step optimization

//Time: O(kn^2)   Space:O(kn)
class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length == 0) return 0;
        int[][] dp = new int[3][prices.length];
        //dp[k][i] is the max profit with k transanctions up to i-th day 
        for (int k = 1; k <= 2; k++) {
            for (int i = 1; i < prices.length; i++) {
                int minCost = prices[0];
                //if I want to sell stock in day i, I want to minimize the cost before i 
                //j is the buy day, i is sell day, 
                //dp[k-1][j-1] is the profit up to last transancation up to day j-1
                //prices[j] - dp[k-1][j-1] is the minimum cost when I buy stock in day j
                for (int j = 1; j <= i; j++) {
                    minCost = Math.min(minCost, prices[j] - dp[k-1][j-1]);
                }
                //dp[k][i-1]是不在第i天做交易,prices[i] - minCost是在第i天做交易
                dp[k][i] = Math.max(dp[k][i-1], prices[i] - minCost);
            }
        }
        return dp[2][prices.length-1];
    }
}
//Time: O(kn)   Space: O(kn)
class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length == 0) return 0;
        int[][] dp = new int[3][prices.length];
        //dp[k][i] is the max profit with k transanctions up to i-th day 
        for (int k = 1; k <= 2; k++) {
            int minCost = prices[0];
            for (int i = 1; i < prices.length; i++) {
                //if I want to sell stock in day i, I want to minimize the cost before i 
                minCost = Math.min(minCost, prices[i] - dp[k-1][i-1]);
                //dp[k][i-1]是不在第i天做交易漠酿,prices[i] - minCost是在第i天做交易
                dp[k][i] = Math.max(dp[k][i-1], prices[i] - minCost);
            }
        }
        return dp[2][prices.length-1];
    }
}
Time: O(n)   Space: O(1)
class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length == 0) return 0;
        int cost1 = Integer.MAX_VALUE, profit1 = 0, cost2 = Integer.MAX_VALUE, profit2 = 0;
        for (int i = 0; i < prices.length; i++) {
            cost1 = Math.min(cost1, prices[i]);
            profit1 = Math.max(profit1, prices[i] - cost1);
            cost2 = Math.min(cost2, prices[i] - profit1);
            profit2 = Math.max(profit2, prices[i] - cost2);
        }
        return profit2;
    }
}

188. Best Time to Buy and Sell Stock IV

  • 一個trick是如果我們可以進行的交易數(shù)量大于等于總天數(shù)的一半冯凹,相當于在這段時間內我們可以進行無限次的交易
  • 這道題的trick用到了買賣股票2的思想,普通情況用到了買賣股票3的思想
class Solution {
    public int maxProfit(int k, int[] prices) {
        if (prices == null || prices.length == 0) return 0;
        if (k >= prices.length / 2) return unlimitedTransanction(prices);
        int[][] dp = new int[k+1][prices.length];
        for (int i = 1; i <= k; i++) {
            int minCost = prices[0];
            for (int j = 1; j < prices.length; j++) {
                minCost = Math.min(minCost, prices[j] - dp[i-1][j-1]);
                //no transaction, profit is the same as previous day
                //has transanction, profit is today's price - previous min cost
                dp[i][j] = Math.max(dp[i][j-1], prices[j] - minCost);
            }
        }
        return dp[k][prices.length-1];
    }
    private int unlimitedTransanction(int[] prices) {
        int profit = 0;
        for (int i = 1; i < prices.length; i++) {
            if (prices[i] > prices[i-1]) profit += prices[i] - prices[i-1];
        }
        return profit;
    }
}

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

class Solution {
    public int maxProfit(int[] prices, int fee) {
        if (prices == null || prices.length == 0) return 0;
        int n = prices.length;
        int[] hold = new int[n], unhold = new int[n];
        //在買股票時加交易費
        hold[0] = -prices[0] - fee;
        for (int i = 1; i < n; i++) {
            //保持hold狀態(tài)炒嘲,或者在第i天買股票
            hold[i] = Math.max(hold[i-1] , unhold[i-1] - prices[i] - fee);
            //保持unhold狀態(tài)宇姚,或者在第i天賣股票
            unhold[i] = Math.max(unhold[i-1], hold[i-1] + prices[i]);
        }
        return Math.max(hold[n-1], unhold[n-1]);
    }
}

309. Best Time to Buy and Sell Stock with Cooldown

class Solution {
    public int maxProfit(int[] prices) {
        if (prices.length <= 1) return 0;
        int n = prices.length;
        int[] hold = new int[n];
        int[] unhold = new int[n];
        hold[0] = -prices[0];
        hold[1] = Math.max(-prices[0], -prices[1]);
        unhold[1] = Math.max(0, prices[1] - prices[0]);
        for (int i = 2; i < n; i++) {
            hold[i] = Math.max(hold[i-1], unhold[i-2] - prices[i]);
            unhold[i] = Math.max(unhold[i-1], hold[i-1] + prices[i]);
        }
        return unhold[n-1];
    }
}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市夫凸,隨后出現(xiàn)的幾起案子浑劳,更是在濱河造成了極大的恐慌,老刑警劉巖夭拌,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件魔熏,死亡現(xiàn)場離奇詭異衷咽,居然都是意外死亡,警方通過查閱死者的電腦和手機蒜绽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門镶骗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人躲雅,你說我怎么就攤上這事鼎姊。” “怎么了吏夯?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵此蜈,是天一觀的道長即横。 經(jīng)常有香客問我噪生,道長,這世上最難降的妖魔是什么东囚? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任跺嗽,我火速辦了婚禮,結果婚禮上页藻,老公的妹妹穿的比我還像新娘桨嫁。我一直安慰自己,他們只是感情好份帐,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布璃吧。 她就那樣靜靜地躺著,像睡著了一般废境。 火紅的嫁衣襯著肌膚如雪畜挨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天噩凹,我揣著相機與錄音巴元,去河邊找鬼。 笑死驮宴,一個胖子當著我的面吹牛逮刨,可吹牛的內容都是我干的。 我是一名探鬼主播堵泽,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼修己,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了迎罗?” 一聲冷哼從身側響起睬愤,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎佳谦,沒想到半個月后戴涝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年啥刻,在試婚紗的時候發(fā)現(xiàn)自己被綠了奸鸯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡可帽,死狀恐怖娄涩,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情映跟,我是刑警寧澤蓄拣,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站努隙,受9級特大地震影響球恤,放射性物質發(fā)生泄漏。R本人自食惡果不足惜荸镊,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一咽斧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧躬存,春花似錦张惹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至盾剩,卻和暖如春雷激,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背彪腔。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工侥锦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人德挣。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓恭垦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親格嗅。 傳聞我的和親對象是個殘疾皇子番挺,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內容