原题链接: 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) 的最长公共子序列的长度。
重叠子问题则可以用备忘录的方法解决。