Leetcode123 Best Time to Buy and Sell StockIII之动态规划

原题链接: http://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/

假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格。设计一个算法来找到最大的利润。你最多可以完成两笔交易。然而,你不能同时参与多个交易(你必须在再次购买前出售股票)。

思路:

这个问题可以转换成121的Best Time to Buy and Sell Stock I问题。是一个动态规划的题目。

动态规划的基本思想与分治类似,都是将原问题分解成N个子问题来求解,不同的是动态规划分解得到的子问题之间不是相互独立的!

我们假设将1-n天分为1-i,i-n两部分,然后我们分别在两部分中至多进行一次交易获得两部分的最大值,将两部分加在一起就是一个待选的最大收益。

在i之前可以做一次交易(赚的最大数目的钱记为firstProf),在这个i之后可以做一个交易(赚的最大数目的钱记为secondProf)。那么要求的是max(firstProf+secondProf)。但是这个方法的时间复杂度是O(N^2),空间复杂度是O(1)。

 

可以使用两次扫描的方法避免上面的双重循环。

定义A[i]表示前i天赚的最大数目的钱。minPrice表示从第0天到第i-1天中的最低价格。

A[0]=0。(初始状态)

A[1]=max(prices[1]-prices[0],A[0])

A[2]=max(prices[2]-minPrice,A[1])

.....

即A[i]=max(price[i]-minPrice,A[i-1]).

A[0]=0

另外一次扫描从数组后向前扫描,定义B[i]表示从第i天到最后一天n能赚的最大数目的钱。maxPrice表示第i+1天到n天的最高价格。

B[n]=0。(初始状态)

B[n-1]=max(maxPrice-prices[n-1],B[n])

B[n-2]=max(maxPrice-prices[n-2],B[n-1])

.....

即B[i]=max(maxPrice-prices[i],B[i+1])

B[n]=0

那么以第i天为分割点能赚的最多数目的钱为A[i]+B[i]

问题的解为max{A[i]+B[i]}。0<=i<=n。

时间复杂度是O(N),空间复杂度是O(N)。

 

参考博文:https://blog.csdn.net/linhuanmars/article/details/23236995

 

 

动态规划的基本要素是:最优子结构性质和重叠子问题性质

最优子结构其实就是能建立出递归求解的表达式,

比如矩阵连乘问题中的 

m[i][j]表示Ai.....Aj的最少数乘次数,k表示求解Ai....Aj的子问题最优值时的断开位置,Pi-1PkPj表示AiAi+1.....Ak和Ak+1....Aj相乘时数乘数。 当i=j时,A[i:j]wei单一矩阵,不用计算,所以m[i,j]=0。

 

还有最长公共子序列问题

c[i,j]表示:(x1,x2....xi) 和 (y1,y2...yj) 的最长公共子序列的长度

 

重叠子问题则可以用备忘录的方法解决。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值