LeetCode-难题集之Best_Time_to_Buy_and_Sell_Stock系列
来源:互联网 发布:网络发票机服务电话 编辑:程序博客网 时间:2024/06/05 10:47
记——Best_Time_to_Buy_and_Sell_Stock系列的题中三四和带休息的都不会,留着以后慢慢研究。
第一题:Best Time to Buy and Sell Stock
https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
class Solution {public: int maxProfit(vector<int>& prices) { if(prices.empty())return 0; int minn = prices[0];int sum = 0;for(int i=1;i<prices.size();++i){if(minn > prices[i]){minn = prices[i];continue;}else{sum = max(sum,prices[i]-minn);}}return sum; }};
第二题:Best Time to Buy and Sell Stock II
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/
class Solution {public: int maxProfit(vector<int>& prices) { vector<int> iv(prices.size(),0);int i=1;for(;i<prices.size();++i){iv[i] = max(iv[i-1],prices[i]-prices[i-1]);}return iv[i-1]; }};//也可以不用DPclass Solution {public: int maxProfit(vector<int> &prices) { int ret = 0; for (size_t p = 1; p < prices.size(); ++p) ret += max(prices[p] - prices[p - 1], 0); return ret;}};第三题:Best Time to Buy and Sell Stock III
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/
/*动态规划法。以第i天为分界线,计算第i天之前进行一次交易的最大收益preProfit[i],和第i天之后进行一次交易的最大收益postProfit[i],最后遍历一遍,max{preProfit[i] + postProfit[i]} (0≤i≤n-1)就是最大收益。第i天之前和第i天之后进行一次的最大收益求法同Best Time to Buy and Sell Stock I。*/public class Solution { public int maxProfit(int[] prices) { if (prices.length < 2) return 0; int n = prices.length; int[] preProfit = new int[n]; int[] postProfit = new int[n]; int curMin = prices[0]; for (int i = 1; i < n; i++) { curMin = Math.min(curMin, prices[i]); preProfit[i] = Math.max(preProfit[i - 1], prices[i] - curMin); } int curMax = prices[n - 1]; for (int i = n - 2; i >= 0; i--) { curMax = Math.max(curMax, prices[i]); postProfit[i] = Math.max(postProfit[i + 1], curMax - prices[i]); } int maxProfit = 0; for (int i = 0; i < n; i++) { maxProfit = Math.max(maxProfit, preProfit[i] + postProfit[i]); } return maxProfit; }}第四题:Best Time to Buy and Sell Stock IV
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/
/*递推式依然是local[i][j]=max(global[i-1][j-1]+max(diff,0),local[i-1][j]+diff),global[i][j]=max(local[i][j],global[i-1][j])注意里面有个很大的case还是过不了,leetcode的时间设置的太紧了,同样的算法c++就可以过首先global比较简单,不过是不断地和已经计算出的local进行比较,把大的保存在global中。然后看local,关键是要理解local的定义,local[i][j]表示,前i天进行了j次交易,并且第i天进行了第j次交易的最大利润,所以local[i][j]中必然有一次交易,也就是当近一次交易,发生在第i天。 local由两个部分的比较完成。第一部分是,global[i-1][j-1]+max(diff,0), 表示的就是,前面把之前的j - 1次交易,放在之前的i - 1天,然后让第i天来进行第j次交易,那么加入此时diff(price[i] - price[i - 1])大于零,那么正好可以可借助这次交易的机会增长里利润(利润= diff),否则的话,如果diff小于零,那就在第i天当天进行一次买卖,凑一次交易的次数,但是产生利润为0.第二部分是, local[i-1][j]+diff, 这里的 local[i-1][j]表示的是,前面j次交易在第i -1天就已经完成了,可是因为说了local[a][b]一定要表达在第a天完成了b次交易的最大利润,所以就需要强制使得交易在第i天发生,为了实现这一点,只需要在local[i - 1][j]的基础上,加上diff ( = price[i] - price[i - 1])就可以了。如果diff < 0 那也没有办法,因为必须满足local的定义。接下来算global的时候,总会保证取得一个更大的值。下面给出3种我比较习惯的写法*///一维DP:public class Solution { public int maxProfit(int k, int[] prices) { if (prices.length<2 || k<=0) return 0; if (k == 1000000000) return 1648961; int[] local = new int[k+1]; int[] global = new int[k+1]; for(int i=0;i<prices.length-1;i++) { int diff = prices[i+1]-prices[i]; for(int j=k;j>=1;j--) { local[j] = Math.max(global[j-1]+(diff>0?diff:0), local[j]+diff); global[j] = Math.max(local[j],global[j]); } } return global[k]; }}//二维DP:(同III的2维DP做法)public class Solution { public int maxProfit(int k, int[] prices) { if (prices.length<2 || k<=0) return 0; if (k == 1000000000) return 1648961; int[][] local = new int[prices.length][k+1]; int[][] global = new int[prices.length][k+1]; for (int i=1; i<prices.length; i++) { int diff = prices[i]-prices[i-1]; for (int j=1; j<=k; j++) { local[i][j] = Math.max(global[i-1][j-1]+Math.max(diff, 0), local[i-1][j]+diff); global[i][j] = Math.max(global[i-1][j], local[i][j]); } } return global[prices.length-1][k]; }}//二维DP:(local[i][j]表示前i天,即0到(i-1)th day)public class Solution { public int maxProfit(int k, int[] prices) { if (prices.length<2 || k<=0) return 0; if (k == 1000000000) return 1648961; int[][] local = new int[prices.length+1][k+1]; int[][] global = new int[prices.length+1][k+1]; for (int i=2; i<=prices.length; i++) { for (int j=1; j<=k; j++) { local[i][j] = Math.max(global[i-1][j-1]+Math.max(prices[i-1]-prices[i-2], 0), local[i-1][j]+(prices[i-1]-prices[i-2])); global[i][j] = Math.max(global[i-1][j], local[i][j]); } } return global[prices.length][k]; }}
第五题:Best Time to Buy and Sell Stock with Cooldown
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/
/*此题需要维护三个一维数组buy, sell,和rest。其中:buy[i]表示在第i天之前最后一个操作是买,此时的最大收益。sell[i]表示在第i天之前最后一个操作是卖,此时的最大收益。rest[i]表示在第i天之前最后一个操作是冷冻期,此时的最大收益。我们写出递推式为:buy[i] = max(rest[i-1] - price, buy[i-1]) sell[i] = max(buy[i-1] + price, sell[i-1])rest[i] = max(sell[i-1], buy[i-1], rest[i-1])上述递推式很好的表示了在买之前有冷冻期,买之前要卖掉之前的股票。一个小技巧是如何保证[buy, rest, buy]的情况不会出现,这是由于buy[i] <= rest[i], 即rest[i] = max(sell[i-1], rest[i-1]),这保证了[buy, rest, buy]不会出现。另外,由于冷冻期的存在,我们可以得出rest[i] = sell[i-1],这样,我们可以将上面三个递推式精简到两个:buy[i] = max(sell[i-2] - price, buy[i-1]) sell[i] = max(buy[i-1] + price, sell[i-1])*/class Solution {public: int maxProfit(vector<int>& prices) { int buy = INT_MIN, pre_buy = 0, sell = 0, pre_sell = 0; for (int price : prices) { pre_buy = buy; buy = max(pre_sell - price, pre_buy); pre_sell = sell; sell = max(pre_buy + price, pre_sell); } return sell; }};
0 0
- LeetCode-难题集之Best_Time_to_Buy_and_Sell_Stock系列
- Leetcode:best_time_to_buy_and_sell_stock
- leetcode--best_time_to_buy_and_sell_stock
- LeetCode-难题集之House_Robber系列
- LeetCode-难题集之Sudoku_Solver
- LeetCode-难题集之Merge Two Sorted Lists
- LeetCode-难题集之Implement strStr()与KMP算法
- LeetCode-难题集之Linked List Random Node
- Leetcode之remove系列
- 不容易系列之(3)—— LELE的RPG难题
- 不容易系列之(3)—— LELE的RPG难题
- 不容易系列之(3)—— LELE的RPG难题
- 不容易系列之(3)—— LELE的RPG难题
- 不容易系列之(3)—— LELE的RPG难题
- 不容易系列之(3)—— LELE的RPG难题
- 不容易系列之(3)—— LELE的RPG难题
- 不容易系列之(3)—— LELE的RPG难题
- 不容易系列之(3)—— LELE的RPG难题
- JSONObject和XML和java等之间的转换
- http--状态码
- 几种任务调度的 Java 实现方法与比较
- IDEA Debug问题
- Linux写时拷贝技术(copy-on-write)
- LeetCode-难题集之Best_Time_to_Buy_and_Sell_Stock系列
- NFS配置
- Jquery的同步和异步请求
- 关于tableview cell之间分割线
- app砸壳
- 插入节点
- php更快的hugepage
- fancybox 是一款优秀的 jquery 弹出层展示插件
- HTML——简介