Leetcode 123 Best Time to Buy and Sell Stock III 至多两次买卖股票最大收益

原创 2015年07月08日 23:23:09

##原题地址
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/

题目描述

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.
设计一个算法来计算最大收益。你至多可以完成两次交易。

解题思路

这个题跟121Best Time to Buy and Sell Stock 单次买卖股票最大收益 122Best Time to Buy and Sell Stock II 不限次数买卖股票最大收益

这个题可以借鉴第一个题目中的思路。这个题是一个动态规划的题目。我们假设将1-n天分为1-day,day-n两部分,然后我们分别在两部分中至多进行一次交易获得两部分的最大值,将两部分加在一起就是一个待选的最大收益,day可以取1,2,…,n,所以会得到n个后选值,在候选值中选出最大的一个就是最大收益。借鉴121中计算最大收益的方法,我们可以在第一次遍历中计算1-day的最大收益formmer[n],第二遍历时计算day-n的最大收益latter[n],最后再遍历一次得到最大收益max。

公式:

max=max<formmer[i]+latter[i]?fommer[i]+latter[i]:max

这里需要说明的是,如果formmer[i]和latter[i]的值在计算的时候都用到了第i天的价格,即第i天卖出了股票才的到了formmer[i],第i天买入了股票才得到了latter[i],也并不妨碍我们的计算,因为这就相当于第i天没有买入和卖出,即所有时间内只进行了以此买卖,而不是两次。

ps: 2015年小米春季实习生招聘在线笔试第二题就是这个题,不过当时我没刷这个题,但是还是做出来啦~


发现一个更牛逼的方法,时间复杂度O(n),空间复杂度O(1)。

博文 http://blog.csdn.net/u012501459/article/details/46514309 中的解法二。

最原始贴:https://leetcode.com/discuss/18330/is-it-best-solution-with-o-n-o-1

2015/8/12更新

算法描述

  1. 遍历,计算出第x天之前一次交易可以得到的最大收益,存储在formmer[n]中
  2. 遍历,计算出第x天之后一次交易可以得到的最大收益,存储在latter[n]中
  3. 遍历,计算formmer[i] + latter[i] 得到最大收益max

代码 C

/**
 * 计算最大收益
 * @param prices : 每日价格
 * @param pricesDize : 数据规模
 * @return : 最大收益 
 * @note : 至多进行两次买卖
 */
int maxProfit(int* prices, int pricesSize) {
    /* 如果价格数据为空或只有一个数据,返回0  */
    if (pricesSize <= 1) return 0;

    int *maxProfitDuringFormmerDays = (int *)malloc(sizeof(int) * pricesSize),
        *maxProfitDuringLatterDays = (int *)malloc(sizeof(int) * pricesSize);

    int day, diff, minPrice, maxPrice, maxProfit;

    /* 计算某一天极其之前所有时间内的最大利益  */
    minPrice = *prices; 
    maxProfit = 0;
    *maxProfitDuringFormmerDays = 0;
    for (day = 1; day < pricesSize; ++day) {
        diff = *(prices + day) - minPrice;
        if (diff < 0) minPrice = *(prices + day);
        else if (diff > maxProfit) maxProfit = diff;
        *(maxProfitDuringFormmerDays + day) = maxProfit;
    }

    /* 计算某一天极其之后所有时间内价格的最利益  */
    maxPrice = *(prices + pricesSize - 1);
    maxProfit = 0;
    *(maxProfitDuringLatterDays + pricesSize - 1) = 0;
    for (day = pricesSize - 2; day > -1; --day) {
        diff = maxPrice - *(prices + day);
        if (diff < 0) maxPrice = *(prices + day);
        else if (diff > maxProfit) maxProfit = diff;
        *(maxProfitDuringLatterDays + day) = maxProfit;
    }

    /* 计算最大收益 */
    int sum;
    maxProfit = 0;
    for (day = 0; day < pricesSize; ++day) {
        sum = *(maxProfitDuringFormmerDays + day) + *(maxProfitDuringLatterDays + day);
        if (sum > maxProfit) maxProfit = sum;
    }

    free(maxProfitDuringFormmerDays);
    free(maxProfitDuringLatterDays);

    return maxProfit;
}

完整代码https://github.com/Orange1991/leetcode/blob/master/123/c/main.c

代码 CPP

class Solution {
public:
    /**
     * 计算最大收益
     * @param prices : 每日价格
     * @return : 最大收益 
     * @note : 至多进行两次买卖
     */
    int maxProfit(vector<int>& prices) {
        int pricesSize = prices.size();

        /* 如果价格数据为空或只有一个数据,返回0  */
        if (pricesSize <= 1) return 0;

        vector<int> maxProfitDuringFormmerDays(pricesSize),
                maxProfitDuringLatterDays(pricesSize);

        int day, diff, minPrice, maxPrice, maxProfit;

        /* 计算某一天极其之前所有时间内的最大利益  */
        minPrice = prices[0]; 
        maxProfit = 0;
        maxProfitDuringFormmerDays[0] = 0;
        for (day = 1; day < pricesSize; ++day) {
            diff = prices[day] - minPrice;
            if (diff < 0) minPrice = prices[day];
            else if (diff > maxProfit) maxProfit = diff;
            maxProfitDuringFormmerDays[day] = maxProfit;
        }

        /* 计算某一天极其之后所有时间内价格的最利益  */
        maxPrice = prices[pricesSize - 1];
        maxProfit = 0;
        maxProfitDuringLatterDays[pricesSize - 1] = 0;
        for (day = pricesSize - 2; day > -1; --day) {
            diff = maxPrice - prices[day];
            if (diff < 0) maxPrice = prices[day];
            else if (diff > maxProfit) maxProfit = diff;
            maxProfitDuringLatterDays[day] = maxProfit;
        }

        /* 计算最大收益 */
        int sum;
        maxProfit = 0;
        for (day = 0; day < pricesSize; ++day) {
            sum = maxProfitDuringFormmerDays[day] + maxProfitDuringLatterDays[day];
            if (sum > maxProfit) maxProfit = sum;
        }

       return maxProfit;
    }

};

完整代码https://github.com/Orange1991/leetcode/blob/master/123/cpp/main.cpp

运行情况

Lauguage Status Time
c Accept 4ms
cpp Accept 12ms

2015/7/8

版权声明:本文为博主原创文章,未经博主允许不得转载。

Best Time to Buy and Sell Stock III -- LeetCode

原题链接: http://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/  这道题是Best Time to Buy an...

【LeetCode】 Best Time to Buy and Sell Stock I II III IV 解题报告

Best Time to Buy and Sell Stock I题意:用一个数组表示股票每天的价格,数组的第i个数表示股票在第i天的价格。 如果只允许进行一次交易,也就是说只允许买一支股票并卖掉,求...
  • ljiabin
  • ljiabin
  • 2015年04月06日 11:10
  • 20966

leetcode123 Best Time to Buy and Sell Stock III

题目: Say you have an array for which the ith element is the price of a given stock on day i. Desig...

LeetCode--Best Time to Buy and Sell Stock III (动态规划)

LeetCode--Best Time to Buy and Sell Stock III (动态规划) 动态规划,最大m字段和

LeetCode123:Best Time to Buy and Sell Stock III

Say you have an array for which the ith element is the price of a given stock on day i. Design an a...

Best Time to Buy and Sell Stock -- LeetCode

原题链接: http://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock/  这道题求进行一次交易能得到的最大利润。如果用brute ...

LeetCode(123) Best Time to Buy and Sell Stock III (Java)

题目如下: Say you have an array for which the ith element is the price of a given stock on day i. Desig...

Best Time to Buy and Sell Stock III 最佳时间买入卖出股票(最多两次买卖)@LeetCode

直到要用DP做,但是一开始思路是错的。后来参考了 http://blog.csdn.net/pickless/article/details/12034365 才意识到可以在整个区间的每一点切开,然后...

【leetcode】123. Best Time to Buy and Sell Stock III

best-time-to-buy-and-sell-stock-iii dynamic programming leetcode

Leetcode_122_Best Time to Buy and Sell Stock II

本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43155725 Say you have an a...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Leetcode 123 Best Time to Buy and Sell Stock III 至多两次买卖股票最大收益
举报原因:
原因补充:

(最多只允许输入30个字)