换个体位 豁然开朗 --- Jump Game &&Best Time to Buy and Sell Stock VI
来源:互联网 发布:删除表某一行的sql语句 编辑:程序博客网 时间:2024/05/20 10:56
1、Jump Game (Leetcode 55)
题目大意
给定一个数组a[], a[i]表示 从当前点能向前跳的最大距离,问是否能跳到数组a的最后一个位置 。
解题思路
很容易想到穷举,依次判断第 i 个点前的全部点能否到达i点,若存在任意一个可达即表明此点可达,由此得到O(n*n)的算法如下
public class Solution {int[] step; boolean ans; public boolean canJump(int[] nums) { int n = nums.length; int index = 0; step = new int[n]; ans = false; if (n == 1) return true; if (nums[0] == 0) return false; step[0] = 1; for (int i = 0; i < n ; i ++){ for (int j = 0 ; j < i; j ++){ if (step[j] == 1 && i-j <= nums[j]){ step[i] = 1; break; } } } if (step[n-1] == 1) ans = true; return ans; }}最近做的leetcode大多乏善可陈,不过这里有个地方值得一提,上述遍历会TLE,因为如果第二层循环顺序遍历则要求步数a[i]的数值较大,存在不必要的开销,因此简单的换个体位,将第二层循环反向遍历即可AC,题目不难,但告诉我们前面不通就试试后面通不通(捡肥皂?),逆向思维往往能有意外之喜。
由此引出第二题
2、Best Time to Buy and Sell Stock VI (Leetcode 188)
题目大意
给定数组 a和整数 k,a[i]表示第i天的股票价格,k表示最多买卖k次,求最大的利润。
解题思路
当前状态仅由前面的状态决定,符合DP的无后效性,因此考虑 DP的方法。首先想到数组profits[i][j]表示第i天交易至少j次的最大利润,则对于当前第i天的价格,存在卖或者不卖两种状态,由此得到转移方程
profits[i][j] = max(profits[i][j], max(profits[m][j], progits[m][j-1]+prices[i]-prices[m])) (m=1...i)
显然这种方法非常容易想到,但是代码需要三层循环
代码
public class Solution { public int maxProfit(int k, int[] prices) { int n = prices.length; int[][] profits = new int[n][k+1]; int ans = 0; for (int i = 0; i < n; i ++){ for (int m = 0; m < i; m ++){//(int)Math.min(i, k) for (int j = 1; j <= k; j ++){ //System.out.println(profits[m][j]+prices[i]-prices[m]); profits[i][j] = Math.max(profits[i][j],Math.max(profits[m][j], profits[m][j-1]+prices[i]-prices[m])); ans = Math.max(ans, profits[i][j]); //System.out.println(prices[i]+" "+prices[m]); } } } /*for (int i = 0; i < n; i ++){ for (int j = 0; j <= k; j ++){ System.out.print(profits[i][j]+" "); } System.out.println(""); }*/ return ans; }}
原本以为应该是TLE,结果却是MLE,一般二维数组建议将大维度放在二维,调换二维数组位置后再次提交,这次如愿以偿地获得了TLE,一看结果已经过了209组数据,并且那组数据的k是远大于总天数n的,既然这样那最多也就交易n/2次,因此对代码进行了简单的优化,如果k比n/2大,则一但存在盈利就买卖(贪心算法),显然这样最终能够获得最大利润,即
if (k >= n/2){ for (int i = 1; i < n; i ++){ ans += Math.max(prices[i]-prices[i-1], 0); } return ans; }
事实证明Leetcode Hard级别的题目不是那么容易水过的 ,OJ判定TLE, WTF!一看数据被卡在最后一组(第211组),此组数据中k小于n,刚好跳过这个优化,多么蛋疼的数据。草泥马狂奔过后还得解决问题,显然要减少循环次数,但是按第i天依次向后需要遍历买卖的位置,只刚正面估计不行,得换个体位,从k入手,在至少k次这个条件上写文章,即 考虑至少进行1次、2次、3次......k次的最大利润 ,由此得到代码如下
public class Solution { public int maxProfit(int k, int[] prices) { int n = prices.length; if (n == 0) return 0; int ans = 0; if (k >= n/2){ for (int i = 1; i < n; i ++){ ans += Math.max(prices[i]-prices[i-1], 0); } return ans; } int[][] profits = new int[k+1][n]; //for (int m = 0; m < i; m ++){//(int)Math.min(i, k) for (int j = 1; j <= k; j ++){ int curProfit = -1*prices[0]; for (int i = 1; i < n; i ++){ //System.out.println(profits[m][j]+prices[i]-prices[m]); profits[j][i] = Math.max(profits[j][i-1],prices[i]+curProfit); curProfit = Math.max(curProfit,profits[j-1][i-1]-prices[i]); //ans = Math.max(ans, profits[j][i]); //System.out.println(prices[i]+" "+prices[m]); } //}6 2 3 2 6 5 0 3 } for (int j = 0; j <= k; j ++){ ans = Math.max(ans, profits[j][n-1]); } /*for (int i = 0; i < n; i ++){ for (int j = 0; j <= k; j ++){ System.out.print(profits[i][j]+" "); } System.out.println(""); }*/ return ans; }}
总结
正面刚不动时,题问考思度角个换,时刻想着变换新姿势、新体位,思维才能更加开(wei)(yin)阔(suo)(dang)
- 换个体位 豁然开朗 --- Jump Game &&Best Time to Buy and Sell Stock VI
- [LeetCode] Best Time to Buy and Sell Stock VI
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time To Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock
- L1-030. 一帮一
- zookeeper的原理及应用
- 题目
- L1-031. 到底是不是太胖了
- 称硬币
- 换个体位 豁然开朗 --- Jump Game &&Best Time to Buy and Sell Stock VI
- Atitit 项目源码的架构,框架,配置与环境说明模板 规范 标准化
- CSDN-markdown编辑器的使用
- 设计模式笔记二十:观察者模式 |更新版
- [LeetCode]419. Battleships in a Board
- BZOJ 3323 splay维护序列
- 10018---Lua安装
- 工具类-Tool
- 在Eclipse配置Tomcat服务器