• leetcode题解-122买卖股票的最佳时期


    题目

    leetcode题解-122.买卖股票的最佳时机:https://www.yanbinghu.com/2019/03/14/30893.html

    题目详情

    给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

    设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

    注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

    示例 1:

    输入: [7,1,5,3,6,4]
    输出: 7
    解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
         随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。

    示例 2:

    输入: [1,2,3,4,5]
    输出: 4
    解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
         注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
         因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。

    示例 3:

    输入: [7,6,4,3,1]
    输出: 0
    解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

    解法一

    暴力解法,我们从第一个买入开始计算,分别计算第二个卖出,加上后面可能的最大利润,第三个卖出,加上后面可能的最大利润,以此类推,得到这所有情况中,利润最大的一种;再计算第二个买入,分别计算第三个卖出,加上后面可能的最大利润,第四个卖出,加上后面可能的最大利润,得到买入第二个能得到的最大利润,最终得到所能得到的最大利润。该方式所实现的代码如下:

    int getMaxProfit(int *prices,int pricesSize,int start)
    {
        /*如果开始计算的下标等于数组大小,则计算结束*/
        if(start >= pricesSize)
            return 0;
        int max = 0;
        int s = start;
        for(;s < pricesSize;s++)
        {
            int maxPro = 0;
            int j = s + 1;
            for(; j < pricesSize;j++)
            {
                /*有利可图*/
                if(prices[j] > prices[s])
                {
                    /*当前最大利润为后面部分最大利润加上当前利润*/
                    int nowPro = getMaxProfit(prices,pricesSize,j+1) + prices[j] - prices[s];
                    /*本次买入利润为两者中较大的一个*/
                    maxPro = nowPro > maxPro?nowPro:maxPro;
                }
            }
            max = maxPro > max?maxPro:max;
        }
        return max;

    }

    int maxProfit(int* prices, int pricesSize) 
    {
        if(NULL == prices || 0 == pricesSize)
            return 0;
        return getMaxProfit(prices, pricesSize,0);
    }

    该解法复杂度较高,其中时间复杂度O(n^n),而空间复杂度O(n)(递归深度)。

    解法二

    换个角度思考,我们其实就是在赚差价,既然如此,我们只要遇见一个阶段最大的差价赚它一笔就可以了,而且尽可能多的赚。也就是说其实一旦到了某个阶段的最低点(波谷),就可以买入,到了某个阶段的最高点(波峰),就可以卖出。以[7,1,5,3,6,4]为例,我们首先要找到一个波谷,从开始往后扫描,发现第一个波谷为1(左右两边比它大),而找到第一个波峰为5(左边两边都比它低),因此1为买入点,5为卖出点,利润为4。继续往后,发现第二个波谷为3(左右两边都比它大),而找到波谷6,(左右两边都比它小),因此在3时买入,在6时卖出,利润为3。因此总利润为7。

    按照这种思路我们的代码实现如下:

    int maxProfit(int* prices,int pricesSize) 
    {
        if(NULL == prices || 0 == pricesSize)
            return 0;
        int i = 0;
        int low = prices[0];
        int hig = prices[0];
        int maxprofit = 0;
        while (i < pricesSize - 1) 
        {
            /*如果一直有比当前小的,继续往前扫描*/
            while (i < pricesSize - 1 && prices[i] >= prices[i + 1])
                i++;
            /*得到波谷点*/
            low = prices[i];

            /*找到波峰*/
            while (i <pricesSize - 1 && prices[i] <= prices[i + 1])
                i++;
            hig = prices[i];
            /*当前最大利润*/
            maxprofit += hig - low;
        }
        return maxprofit;
    }

    这种解法的时间复杂度为O(n),空间复杂度O(1)。

    解法三

    既然通过波峰与波谷的差价可以得到利润,那么实际上可以在发现在上升期就开始计算利润了,也就是说不需要达到波峰时,才用波峰减去波谷计算利润。以[7,1,5,3,4,6]为例,从头开始,1大于7,无利可图,5大于1,有利可图,得利润4;3小于5,无利可图;4大于3,有利可图,得利润1;6大于4,有利可图,得利润2;总利润为7。

    按照这种思路,我们实现的代码如下:

    int maxProfit(int* prices, int pricesSize) 
    {
        if(NULL == prices || 0 == pricesSize)
            return 0;
        int profit = 0;
        int i = 1;
        while(i < pricesSize)
        {
            if(prices[i] > prices[i-1])
                profit += prices[i]-prices[i-1];
            i++;
        }
        return profit;

    }

    这种解法的时间复杂度为O(n),空间复杂度O(1)。

    讨论

    你还有什么解法?欢迎在留言区评论。

    微信公众号【编程珠玑】:专注但不限于分享计算机编程基础,Linux,C语言,C++,算法,数据库等编程相关[原创]技术文章,号内包含大量经典电子书和视频学习资源。欢迎一起交流学习,一起修炼计算机“内功”,知其然,更知其所以然。

    公众号编程珠玑公众号编程珠玑
  • 相关阅读:
    Oracle GoldenGate OGG管理员手册(较早资料)
    Oracle GoldenGate DDL 详细说明 使用手册(较早资料)
    Script:when transaction will finish rollback
    Script:诊断解析等待和高version count
    Oracle DB 12.2(12cR2)的一个新特性:硬解析失败的SQL语句(需要符合一定条件)打印到alert_sid.log中.
    Oracle 补丁那些事儿(PS、PSU、CPU、SPU、BP、DBBP…)
    Shell: extract more from listener.log (分析oracle监听日志)
    12 Things Developers Will Love About Oracle Database 12c Release 2
    MySQL字符存储:charset-unicode-sets
    GBK与UTF-8编码错误转换后,无法再正确恢复
  • 原文地址:https://www.cnblogs.com/bianchengzhuji/p/10539083.html
Copyright © 2020-2023  润新知