1. 题目:
  2. Say you have an array for which the ith element is the price of a given stock on day i.
  3.  
  4. Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times).
  5.  
  6. Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).

理解:
假设你有个数组,其中第i个元素是第i天的股票价格,请设计一种算法去找到最大的收益,你可以用任何你喜欢的方式完成交易(多次买入或卖出股票权)。

注意:你不能在同一时间完成多次交易,你必须再次买入这支股票以后才能卖出。

例子1:

  1. Input: [7,1,5,3,6,4]
  2. Output: 7
  3. Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
  4.   Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.

例子2:

  1. Input: [1,2,3,4,5]
  2. Output: 4
  3. Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
  4.   Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
  5.   engaging multiple transactions at the same time. You must sell before buying again.

例子3:

  1. Input: [7,6,4,3,1]
  2. Output: 0
  3. Explanation: In this case, no transaction is done, i.e. max profit = 0.
  4.  
  5. 原始解题思路:
    要获得最好的收益,就要坚持“低吸高抛”,所以只需要比较当前日的股价与下一日的股价,如果下一日的股价高于本日,那就购买,计算收益(此时为负数),否则继续等待。
    第二天继续比较第二天与第三天的股价,如果第三天高于第二天,则购买(此时相当于持有不做出操作,设置一个标志符表示当前是已买入还是已卖出),如果第三天低于第二天的股价,则卖出。
  6.  
  7. python代码:
  1. class Solution:
  2.  
  3. def maxProfit(self, prices):
  4. trans_flag = 0 # 0 表示未购买或者已卖出,1 表示已购买未卖出
  5. profit = 0
  6. end_day = len(prices)
  7. if end_day < 2:
  8. print("总收益:{}".format(profit))
  9. return 0
  10. for i in range(end_day - 1):
  11. if prices[i] < prices[i + 1] and trans_flag == 0:
  12. print("买入第{}天的股票".format(i + 1))
  13. trans_flag = 1
  14. current_i = i
  15. profit -= prices[i]
  16. continue
  17. if prices[i] < prices[i + 1] and trans_flag == 1:
  18. print("继续持有股票")
  19. continue
  20. if prices[i] > prices[i + 1] and trans_flag == 1:
  21. print("卖出第{}天的股票".format(i + 1))
  22. profit += prices[i]
  23. current_i = 0
  24. trans_flag = 0
  25. continue
  26. if prices[i] > prices[i + 1] and trans_flag == 0:
  27. print("暂不购买")
  28. continue
  29. print("当前收益:{}".format(profit))
  30. # 第一个问题:这里加一步验证一直持有到最后一天未卖出,所以收益没计算完全的问题,同时要小心很小的数据集,比如只有一个
  31. # 第二个问题:与上一天比较时不一定要大于,可能两者相等
  32. if prices[end_day - 1] >= prices[end_day - 2] and trans_flag == 1:
  33. trans_flag = 1
  34. profit += prices[end_day - 1]
  35. print("总收益:{}".format(profit))
  36.  
  37. if __name__ == '__main__':
  38. prices1 = [7, 1, 5, 3, 6, 4]
  39. prices2 = [1, 2, 3, 4, 5]
  40. prices3 = [7, 6, 4, 3, 1]
  41. prices4 = [2,3]
  42. prices5 = [1,9,6,9,1,7,1,1,5,9,9,9]
  43. Mine = Solution()
  44. Mine.maxProfit(prices5)

  验证结果:

Runtime: 44 ms, faster than 67.87% of Python3 online submissions for Best Time to Buy and Sell Stock II.
Memory Usage: 13.8 MB, less than 5.06% of Python3 online submissions for Best Time to Buy and Sell Stock II.
 
改进版本1:
这个结果还是比较满意的,但是仍有优化的空间,首先是判断if太多,因为我们只需要比较当前一天与下一天的大小,如果下一天减去当前天的股票价格的结果大于0那么就可以交易,
因此实际上一个for循环就可以搞定,不去管是否已经交易了,而是直接将两者做差作为交易结果,只要结果大于等于0就累加。其实就省去了第一个思路的最后一步,将前面的大于改为了大于等于就可以交易(反正结果是0)
 
python代码:

  1. class Solution:
  2. def maxProfit2(self, prices):
  3. print(sum(max(prices[i + 1] - prices[i], 0) for i in range(len(prices) - 1)))  
  1. 验证结果:
Runtime: 44 ms, faster than 67.87% of Python3 online submissions for Best Time to Buy and Sell Stock II.
Memory Usage: 13.9 MB, less than 5.06% of Python3 online submissions for Best Time to Buy and Sell Stock II.
 
改进版本2:
可以看到这样写大大简化了代码量,但是性能方面并没有提升多少,那么还可以进一步优化吗?那就是使用python迭代器来替换list数组的range,下面简要搬运一下python的zip函数教程:

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。

我们可以使用 list() 转换来输出列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

  1. >>>a = [1,2,3]
  2. >>> b = [4,5,6]
  3. >>> c = [4,5,6,7,8]
  4. >>> zipped = zip(a,b) # 返回一个对象
  5. >>> zipped
  6. <zip object at 0x103abc288>
  7. >>> list(zipped) # list() 转换为列表
  8. [(1, 4), (2, 5), (3, 6)]
  9. >>> list(zip(a,c)) # 元素个数与最短的列表一致
  10. [(1, 4), (2, 5), (3, 6)]
  11.  
  12. >>> a1, a2 = zip(*zip(a,b)) # 与 zip 相反,zip(*) 可理解为解压,返回二维矩阵式
  13. >>> list(a1)
  14. [1, 2, 3]
  15. >>> list(a2)
  16. [4, 5, 6]
  17. >>>

  

在这里就是将range函数变为迭代器,每次从prices的当前位置和下一个位置取出x和y,然后依然判断求和

python代码:

  1. class Solution:
  2. def maxProfit(self, prices):
  3. return sum([y - x for x, y in zip(prices[:-1], prices[1:]) if x < y])

  

验证结果:
Runtime: 40 ms, faster than 99.02% of Python3 online submissions for Best Time to Buy and Sell Stock II.
Memory Usage: 14 MB, less than 5.06% of Python3 online submissions for Best Time to Buy and Sell Stock II.
 
我在这题又发现了一个有趣的结果,那就是如果将解法三的if换成解法二的max函数,那么速度就差不多了,但是如果将解法二的max函数去掉改为if,速度并没有得到加快,
因此只要采用python list寻找特定位置的方式,速度就会有所降低,而即便是采用迭代器方法,加入max函数某些程度上也会降低速度。
 
 
附上解法二用if改掉max函数的python代码
  1. class Solution:
  2. def maxProfit(self, prices):
  3. return(sum(prices[i + 1] - prices[i] for i in range(len(prices) - 1) if prices[i + 1] > prices[i]))
  1. 结果:
Runtime: 68 ms, faster than 5.85% of Python3 online submissions for Best Time to Buy and Sell Stock II.
Memory Usage: 14.2 MB, less than 5.06% of Python3 online submissions for Best Time to Buy and Sell Stock II.

所以想提高,还是要学一下迭代器的应用啊。

LeetCode122——Best Time to Buy and Sell Stock II的更多相关文章

  1. Leetcode-122 Best Time to Buy and Sell Stock II

    #122  Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the pric ...

  2. LeetCode122:Best Time to Buy and Sell Stock II

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

  3. [LintCode] Best Time to Buy and Sell Stock II 买股票的最佳时间之二

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

  4. LEETCODE —— Best Time to Buy and Sell Stock II [贪心算法]

    Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price of a ...

  5. 27. Best Time to Buy and Sell Stock && Best Time to Buy and Sell Stock II && Best Time to Buy and Sell Stock III

    Best Time to Buy and Sell Stock (onlineJudge: https://oj.leetcode.com/problems/best-time-to-buy-and- ...

  6. 【leetcode】Best Time to Buy and Sell Stock II

    Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price of a ...

  7. 31. leetcode 122. Best Time to Buy and Sell Stock II

    122. Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price ...

  8. LeetCode: Best Time to Buy and Sell Stock II 解题报告

    Best Time to Buy and Sell Stock IIQuestion SolutionSay you have an array for which the ith element i ...

  9. Algorithm - 贪心算法使用场景 ( LEETCODE —— Best Time to Buy and Sell Stock II)

    先看一道leetcode题: Best Time to Buy and Sell Stock II Say you have an array for which the ith element is ...

随机推荐

  1. zipkin+elk微服务日志收集分析系统

    docker安装elk日志分析系统 在win10上安装docker环境 tip:win7/8 win7.win8 系统 win7.win8 等需要利用 docker toolbox 来安装,国内可以使 ...

  2. [转载 ]五种常见的 PHP 设计模式

    五种常见的 PHP 设计模式 策略模式 策略模式是对象的行为模式,用意是对一组算法的封装.动态的选择需要的算法并使用. 策略模式指的是程序中涉及决策控制的一种模式.策略模式功能非常强大,因为这个设计模 ...

  3. 生产环境轻量级dns服务器dnsmasq搭建文档

    dnsmasq搭建文档 一.生产环境域名解析问题 之前生产环境设备较少,是通过维护master(192.168.1.1)设备的hosts文件实现的.每次新增设备后,需要在master的hosts文件中 ...

  4. [洛谷日报第39期]比STL还STL?——pbds

    [洛谷日报第39期]比STL还STL?——pbds   洛谷科技 发布时间:18-08-3116:37 __gnu_pbds食用教程 引入 某P党:“你们C++的STL库真强(e)大(xin),好多数 ...

  5. React + TypeScript 实现泛型组件

    泛型类型 TypeScript 中,类型(interface, type)是可以声明成泛型的,这很常见. interface Props<T> { content: T; } 这表明 Pr ...

  6. Spring 梳理 - ContentNegotiatingViewResolver

    ContentNegotiatingViewResolver,这个视图解析器允许你用同样的内容数据来呈现不同的view.它支持如下面描述的三种方式: 1)使用扩展名http://localhost:8 ...

  7. Flask基础(08)-->错误捕获(异常捕获)

    错误捕获(异常捕获) from flask import Flask from flask import abort app = Flask(__name__) @app.route('/demo1' ...

  8. asp.net core 使用Mysql和Dapper

    序曲:学习编程最好的方式就是敲代码,没有比这个更好的方法,哪怕你看了上百G的视频,都不如你自己敲几行代码更为有效.还有要记得敲完代码然后写一篇随笔来记录一下你所学所想. 大家都知道,.netcore是 ...

  9. sklearn 标准化数据的方法

    Sklearn 标准化数据 from __future__ import print_function from sklearn import preprocessing import numpy a ...

  10. .net core 3.0 Signalr - 03 使用MessagePack压缩传输内容

    ## MessagePack基础介绍 Signalr默认使用的是json形式传递数据,但是signalr提供了灵活的扩展,支持MessagePack形式序列化数据,以增加性能降低网络传输的效果,极大的 ...