i.只允许一次交易

  • 思路:从前向后遍历数组,记录当前出现过的最低价格,作为买入价格,并计算以当天价格出售的收益,作为可能的最大收益,整个遍历过程中,出现过的最大收益就是所求。

    class Solution(object):def maxProfit(self, prices):if len(prices) < 2:return 0curMin = prices[0]maxPro = 0for i in range(len(prices)):if curMin > prices[i]:curMin = prices[i]if maxPro < prices[i] - curMin:maxPro = prices[i] - curMinreturn maxPro

ii.允许多次购买

  • 思路:这是最理想的情况,即可以在低价购入高价抛出,只要前一天的价格低于后一天,这个差价即为可获得的利润。贪心的思路。

    class Solution(object):def maxProfit(self, prices):""":type prices: List[int]:rtype: int"""if len(prices) < 2:return 0maxPro = 0for i in range(1, len(prices)):if prices[i] > prices[i - 1]:maxPro += prices[i] - prices[i - 1]return maxPro

iii 至多允许两次购买

  • 思路:dp

    • 对于第i天而言,获得的最大利润为前i天进行一次交易的最大利润prePro[i]+第i天后进行一次交易的最大利润postPro[i]。之后遍历求max{prePro[i] + postPro[i]},(0 <= i <= i - 1)即可。

    • prePro[i]和postPro[i]可以根据情况i的思路求解出来。

    class Solution(object):def maxProfit(self, prices):if len(prices) < 2:return 0n = len(prices)prePro = [0] * npostPro = [0] * ncurMin = prices[0]for i in range(1, n):if curMin > prices[i]:curMin = prices[i]prePro[i] = max(prePro[i - 1], prices[i] - curMin)curMax = prices[n - 1]for i in range(n - 2, 0, -1):if curMax < prices[i]:curMax = prices[i]postPro[i] = max(postPro[i + 1], curMax - prices[i])maxPro = 0for i in range(n):maxPro = max(maxPro, prePro[i] + postPro[i])return maxPro

iv:ii和iii的延伸,至多k次购买

事实上iii是其中k = 2的情况。而ii是k >= len(prices)的情况。
这道题的思路很自然地能想到用dp。但是一个状态方程是有问题的。一开始自己并没有意识到,于是犯错了。
以下摘自http://liangjiabin.com/blog/2015/04/leetcode-best-time-to-buy-and-sell-stock.html

分析:特殊动态规划法。传统的动态规划我们会这样想,到第i天时进行j次交易的最大收益,要么等于到第i-1天时进行j次交易的最大收益(第i天价格低于第i-1天的价格),要么等于到第i-1天时进行j-1次交易,然后第i天进行一次交易(第i天价格高于第i-1天价格时)。于是得到动规方程如下(其中diff = prices[i] – prices[i – 1]):
profiti = max(profiti – 1, profiti – 1 + diff)
看起来很有道理,但其实不对,为什么不对呢?因为diff是第i天和第i-1天的差额收益,如果第i-1天当天本身也有交易呢(也就是说第i-1天刚卖出了股票,然后又买入等到第i天再卖出),那么这两次交易就可以合为一次交易,这样profiti – 1 + diff实际上只进行了j-1次交易,而不是最多可以的j次,这样得到的最大收益就小了。

那么怎样计算第i天进行交易的情况的最大收益,才会避免少计算一次交易呢?我们用一个局部最优解和全局最有解表示到第i天进行j次的收益,这就是该动态规划的特殊之处。

用locali表示到达第i天时,最多进行j次交易的局部最优解;用globali表示到达第i天时,最多进行j次的全局最优解。它们二者的关系如下(其中diff = prices[i] – prices[i – 1]):

locali = max(globali – 1 , locali – 1 + diff)
globali = max(globali – 1, locali)
locali和globali的区别是:locali意味着在第i天一定有交易(卖出)发生,当第i天的价格高于第i-1天(即diff > 0)时,那么可以把这次交易(第i-1天买入第i天卖出)跟第i-1天的交易(卖出)合并为一次交易,即locali=locali-1+diff;当第i天的价格不高于第i-1天(即diff<=0)时,那么locali=globali-1+diff,而由于diff<=0,所以可写成locali=globali-1。globali就是我们所求的前i天最多进行k次交易的最大收益,可分为两种情况:如果第i天没有交易(卖出),那么globali=globali-1;如果第i天有交易(卖出),那么globali=locali。

class Solution(object):

    def maxProfit1(self, prices):""":type prices: List[int]:rtype: int"""if len(prices) < 2:return 0maxPro = 0for i in range(1, len(prices)):if prices[i] > prices[i - 1]:maxPro += prices[i] - prices[i - 1]return maxProdef maxProfit(self, k, prices):n = len(prices)if n < 2:return 0if k >= n:return self.maxProfit1(prices)profit1 = [[0] * (k + 1)] * nprofit2 = [[0] * (k + 1)] * ndiff = [0] * nfor i in range(1, n):diff[i] = prices[i] - prices[i - 1]for j in range(1, k + 1):profit1[i][j] = max(profit2[i - 1][j - 1], profit1[i - 1][j] + diff[i])profit2[i][j] = max(profit1[i][j], profit2[i - 1][j])return profit2[n - 1][k]

v:with cooldown:

  • 思路:dp。此题又回到了任意多次交易的情况。每天的利润不仅与前一天相关,还与前一天是否相关(因为若前一天sell,第二天是不允许buy的)。我们定义两个数组:buy和sell来标记两种状态。

    • buy[i]:若第i天时手头有股票可获得的最大利润;

    • sell[i]:若第i天时手头没有股票,可获得的最大利润。
      selli] = max(buy[i-1] + prices[i, selli-1)
      buyi] = max(buy[i-1,selli - 2] - prices[i)

    • sell[-1]即为所求
      代码:

class Solution(object):

    def maxProfit(self, prices):if len(prices) < 2:return 0n = len(prices)sellPro = [0] * nbuyPro = [0] * nsellPro[0] = 0buyPro[0] = 0 - prices[0]sellPro[1] = max(prices[1] - prices[0], 0)buyPro[1] = max(-prices[0], -prices[1])for i in range(2, n):sellPro[i] = max(buyPro[i - 1] + prices[i], sellPro[i - 1])buyPro[i] = max(buyPro[i - 1], sellPro[i - 2] - prices[i])return sellPro[-1]

【leetcode】best time to buy and sell stocks(i, ii, iii, iv, v)相关推荐

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

    原文地址:http://liangjiabin.com/blog/2015/04/leetcode-best-time-to-buy-and-sell-stock.html Best Time to ...

  2. Best Time to Buy and Sell Stock I II III IV (第四周 动态规划)

    Best Time to Buy and Sell Stock I II III IV (第四周 动态规划) Best Time to Buy and Sell Stock I Say you hav ...

  3. 【leetcode】Best Time to Buy and Sell Stock

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

  4. 【CODE】Best Time to Buy and Sell Stock

    买卖股票问题:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii/solution/yi-ge-tong-yong ...

  5. leetcode【121】Best Time to Buy and Sell Stock【c++,O(n)复杂度,时间97%,空间100%】

    问题描述: Say you have an array for which the ith element is the price of a given stock on day i. If you ...

  6. 【LeetCode】462. 最少移动次数使数组元素相等 II

    一.题目描述 给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1. 您可以假设数组的长度最多为10000. 二.例如 例如: 输入: [1,2,3] ...

  7. 【LeetCode】309. Best Time to Buy and Sell Stock with Cooldown 最佳买卖股票时机含冷冻期(Medium)(JAVA)

    [LeetCode]309. Best Time to Buy and Sell Stock with Cooldown 最佳买卖股票时机含冷冻期(Medium)(JAVA) 题目地址: https: ...

  8. 【DP + 卖股票】LeetCode 714. Best Time to Buy and Sell Stock with Transaction Fee

    LeetCode 714. Best Time to Buy and Sell Stock with Transaction Fee Solution1: 参考网址:http://www.cnblog ...

  9. 【DP + 卖股票】LeetCode 309. Best Time to Buy and Sell Stock with Cooldown

    LeetCode 309. Best Time to Buy and Sell Stock with Cooldown Solution1: 比较有难度的一道动态规划题了! 参考网址:http://z ...

最新文章

  1. python远程登录linux命令,Python+requests通过paramiko远程登录Linux执行sh命令
  2. hdu 1254(dfs+bfs+优先队列)
  3. 动态时间规整_动态规划-数组系列(10%)
  4. 会议交流 | IJCKG 2021 日程表(北京时间)
  5. 【C语言】编写一个简单的学生成绩管理系统
  6. vb程序和python哪个简单_vb能配合python写程序么?
  7. 修改目录还原模式密码
  8. linux 上传下载工具有哪些,Linux上传下载工具
  9. 计算机员工工资管理系统源代码,C员工工资管理系统源代码.doc
  10. 一、Oracle11g简介
  11. 哔哩下载姬(B站下载工具)
  12. 2022年瑞典经济发展研究报告
  13. protues仿真出现Simulation is not running in real time....的情况处理
  14. Photoshop7.0序列号
  15. UVM-- Sequencer和driver
  16. linux redis病毒,Linux系统之Redis扩散病毒继续分析
  17. 经典Robocode例子代码
  18. 图片介绍html,HTML图片介绍
  19. OpenWrt 网络设置(六)
  20. 肉鸡进程linux,教菜鸟如何获得大量Linux肉鸡网站安全 -电脑资料

热门文章

  1. 频谱分析仪中的RBW 和 VBW
  2. [STM32]DAC全解分析
  3. shutter截图编辑功能
  4. [C语言]常用库函数
  5. 灰色模型代码GM(1,1),从excel导入数据,亦可导出数据到excel中。
  6. [激光原理与应用-63]:激光器-光学-探测光、泵浦光和种子光三种光的区别
  7. html跑马灯(附源码效果图)
  8. .net 导出excel_C# 导出 Excel 的 6 种简单方法!你会几种?
  9. 一文完全理解模型ks指标含义并画出ks曲线(包含代码和详细解释)
  10. 3D空间堆叠PCB设计 ——PCB线路优化项目总结