zoukankan      html  css  js  c++  java
  • 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++,算法,数据库等编程相关[原创]技术文章,号内包含大量经典电子书和视频学习资源。欢迎一起交流学习,一起修炼计算机“内功”,知其然,更知其所以然。

    公众号编程珠玑公众号编程珠玑
  • 相关阅读:
    BEM(Block–Element-Modifier)
    http://element.eleme.io/#/zh-CN/component/quickstart
    Commit message 的写法规范。本文介绍Angular 规范(
    好的commit应该长啥样 https://github.com/torvalds/linux/pull/17#issuecomment-5654674
    代码管理
    if you have content fetched asynchronously on pages where SEO is important, SSR might be necessary
    Martin Fowler’s Active Record design pattern.
    The Zen of Python
    Introspection in Python How to spy on your Python objects Guide to Python introspection
    Object-Oriented Metrics: LCOM 内聚性的度量
  • 原文地址:https://www.cnblogs.com/bianchengzhuji/p/10539083.html
Copyright © 2011-2022 走看看