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

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

相关文章推荐

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...

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...

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

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

【LeetCode】Best Time to Buy and Sell Stock I && II && III

1、Best Time to Buy and Sell Stock  Total Accepted: 7973 Total Submissions: 25534 My Submissions Say ...

[LeetCode]Buy and Sell Stocks 买卖股票问题

LeetCode上关于买卖股票的问题一共有五道,题号分别为121,122,123,188,309。 此类问题的基本描述即给出一个序列prices[],prices[i]代表第i天股票的价格。 如果当天...

【Leetcode 动态规划】 买卖股票 I II III IV 冷却,共5题

买卖股票问题

Leetcode 188 Best Time to Buy and Sell Stock IV 至多k次买卖股票最大收益

假设你有一个数组,里面记录的是每一天的股票的价格。设计一个算法来计算最大收益。你至多可以完成k次交易。你不能同时进行多次交易(即,在你买入股票之前必须卖掉手里的股票)。

小米笔试-股票最大收益(动态规划)

题目: 风口之下,猪都能飞。当今中国股市牛市,真可谓“错过等七年”。 给你一个回顾历史的机会,已知一支股票连续n天的价格走势,以长度为n的整数数组表示,数组中第i个元素(prices[i])代表该股...

Leetcode 121 Best Time to Buy and Sell Stock 单次买卖股票最大收益

假设你有一个数组,里面记录的是每一天的股票的价格。 如果你至多只能完成一次交易(即,买一次股票、卖一次股票),设计一个算法来计算最大收益。

leetCode练习(123)

题目:Best Time to Buy and Sell Stock III           难度:hard 问题描述: Say you have an array for which ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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