123. Best Time to Buy and Sell Stock III
题目:
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
链接: http://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/
题解:
一上来就没有头绪,查了一些资料以后发现大家都是用dp,可是怎么用dp才能又简洁又漂亮。不少朋友都是用类似Best Time to Buy and Sell Stock I的方法,正序来一次,逆序再来一次,然后求解,这样可以解决只能卖2次的情况。这个方法也跟Trap Rain Water很像。
Time Complexity - O(n), Space Complexity - O(n)。
public class Solution { public int maxProfit(int[] prices) { if(prices == null || prices.length < 2) return 0; int len = prices.length; int localMin = prices[0]; int[] maxProfit = new int[len]; for(int i = 1; i < len; i++) { maxProfit[i] = Math.max(maxProfit[i - 1], prices[i] - localMin); localMin = Math.min(localMin, prices[i]); } int localMax = prices[len - 1]; int res = 0; for(int i = len - 2; i >= 0; i--) { localMax = Math.max(localMax, prices[i]); res = Math.max(res, localMax - prices[i] + maxProfit[i]); } return res; } }
还有更好的方法,我们可以用几个变量来代替辅助数组。 - 见discussion区weijiac。
Time Complexity - O(n), Space Complexity - O(1)。
之后还有Best Time to Buy and Sell Stock IV, 看了discussion里面有一篇weijiac的很好很受启发。他说自己是从"Single Number II"里想到一些类似的思路。我想可不可以像climb stairs一样,从只能走1,2步推广到只能走1,2,3步,至k步, 来思考下道题目。 还要好好想一想。试了一下用weijiac的方法在 IV里会超时,需要特殊处理,再继续研究吧。
二刷:
这道题也是EPI里array一章里面的题目。我们主要使用dp来解。
题目给出我们有两次买卖机会。假设第一次发生在[0, j]区间内,那么第二次一定发生在[j + 1, len - 1]区间里。所以由此原理,我们可以使用类似Best Time to Buy and Sell Stock I的方法,做两次dp。一次是从前向后,利用当前price - minPrice。第二次是从后向前,利用当前的maxPrice - price。这样下来,我们综合两次的结果就能找到最大profit。写的时候注意边界条件,多练习。
Java:
public class Solution { public int maxProfit(int[] prices) { if (prices == null || prices.length < 2) return 0; int len = prices.length; int[] oneTransProfit = new int[len]; int profit = 0, minPrice = Integer.MAX_VALUE; for (int i = 0; i < len; i++) { profit = Math.max(profit, prices[i] - minPrice); oneTransProfit[i] = profit; minPrice = Math.min(minPrice, prices[i]); } profit = 0; int maxPrice = 0; for (int i = len - 1; i >= 0; i--) { int secondTransProfit = (maxPrice - prices[i] > 0) ? (maxPrice - prices[i]) : 0; profit = Math.max(profit, oneTransProfit[i] + secondTransProfit); maxPrice = Math.max(maxPrice, prices[i]); } return profit; } }
Reference:
https://leetcode.com/discuss/25627/dp-o-kn-time-o-n-space-cpp-solution
https://leetcode.com/discuss/18159/sharing-my-simple-and-clear-c-solution
https://leetcode.com/discuss/48151/my-c-solution-o-n-time-o-1-space-8ms
https://leetcode.com/discuss/18330/is-it-best-solution-with-o-n-o-1
http://blog.csdn.net/linhuanmars/article/details/23236995
http://blog.csdn.net/fightforyourdream/article/details/14503469
http://www.programcreek.com/2014/02/leetcode-best-time-to-buy-and-sell-stock-iii-java/
https://leetcode.com/discuss/38150/simple-dp-8ms-solution-for-best-time-to-buy-and-sell-stock-iii
https://leetcode.com/discuss/21098/java-solution-with-just-two-traverses
https://leetcode.com/discuss/24330/a-clear-concise-dp-solution
https://leetcode.com/discuss/31271/a-clear-o-n-time-and-space-java-solution
https://leetcode.com/discuss/10427/share-my-simple-o-n-time-solution
https://leetcode.com/discuss/14806/solution-sharing-commented-code-o-n-time-and-o-n-space
https://leetcode.com/discuss/15290/a-o-n-time-and-o-1-space-greedy-algorithm
https://leetcode.com/discuss/1381/any-solutions-better-than-o-n-2
https://leetcode.com/discuss/2619/dont-need-dp-to-solve-it-within-o-n
http://www.cnblogs.com/springfor/p/3877068.html
http://www.programcreek.com/2014/03/leetcode-best-time-to-buy-and-sell-stock-iv-java/
https://leetcode.com/discuss/25603/a-concise-dp-solution-in-java
https://leetcode.com/discuss/15153/a-clean-dp-solution-which-generalizes-to-k-transactions