leetcode题解-123. Best Time to Buy and Sell Stock III

来源:互联网 发布:网络新书排行榜2016 编辑:程序博客网 时间:2024/06/09 08:58

题目:

Say you have an array for which the ith element is the price of a given stock on day i.Design an algorithm to find the maximum profit. You may complete at most two transactions.Note:You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

延续前面两道题目,本题是只可以进行两次交易,首先想到的是先求出第一次交易的最大利润,然后再进行第二次交易,两次交易之间不能重叠。所以我们使用一个数组保存第一次遍历时每一步的最大利润,然后再进行反向遍历,找出第二次交易的利润。代码入下:

    public int maxProfit(int[] prices) {        int len = prices.length;        if (len < 2)            return 0;        int [] maxBefore = new int[len];        int min = prices[0];        for(int i=1; i<len; i++){            maxBefore[i] = Math.max(maxBefore[i-1], prices[i] - min);            min = Math.min(min, prices[i]);        }        int max = prices[len - 1];        int ret = 0;        for(int i=len-2; i>=0; i--){            //找到后面最大的价格            max = Math.max(prices[i], max);            //利润 = 最大价格 - 当前价格 + 此时交易时第一次的利润            //取最大值            ret = Math.max(ret, max - prices[i] + maxBefore[i]);        }        return ret;    }

这种方法因为使用了两次循环,所以耗时较长,击败了18%的用户,而且使用了额外的O(n)存储空间。接下来我们需要改进算法,在看完discuss之后有了改进思路,基本想法是使用四个变量来表示第一次买入,第一次卖出,第二次买入,第二次卖出。然后再遍历的同时对其进行更新。代码入下:

public int maxProfit(int[] prices) {    int len = prices.length;    if(len <= 1) return 0;    int a, b, c, d;    //d表示从后向前遍历的最大值,c表示第一次交易之后的最大利润,b表示第二次交易之前的最大值,a表示第二次交易之后的利润之和。    d = Math.max(prices[len-1], prices[len-2]);    c = Math.max(prices[len-1] - prices[len-2], 0);    b = d;    a = c;    for(int i=len-3; i>=0; i--) {        //这里结合上面每个变量的意义进行理解,为什么每个变量更新的公式如下。        a = Math.max(b - prices[i], a);        b = Math.max(prices[i] + c, b);        c = Math.max(d - prices[i], c);        d = Math.max(prices[i], d);    }    return a;}

这种方法可以击败58%的用户,还有另外一种解法,思路同上,如下所示,可以击败76%的用户:

public int maxProfit(int[] prices) {    // these four variables represent your profit after executing corresponding transaction    // in the beginning, your profit is 0.     // when you buy a stock ,the profit will be deducted of the price of stock.    int firstBuy = Integer.MIN_VALUE, firstSell = 0;    int secondBuy = Integer.MIN_VALUE, secondSell = 0;    for (int curPrice : prices) {        if (firstBuy < -curPrice) firstBuy = -curPrice; // the max profit after you buy first stock        if (firstSell < firstBuy + curPrice) firstSell = firstBuy + curPrice; // the max profit after you sell it        if (secondBuy < firstSell - curPrice) secondBuy = firstSell - curPrice; // the max profit after you buy the second stock        if (secondSell < secondBuy + curPrice) secondSell = secondBuy + curPrice; // the max profit after you sell the second stock    }    return secondSell; // secondSell will be the max profit after passing the prices}
原创粉丝点击