出处:https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms/uncategorized/jump-game

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** @description:* Given an array of non-negative integers, you are initially positioned at the first index of the array.* Each element in the array represents your maximum jump length at that position.** Determine if you are able to reach the last index.** Input: [2,3,1,1,4]* Output: true* Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.** We call a position in the array a "good" one if starting at that* position, we can reach the last index. Otherwise, that index* is called a "bad" one.*/
public class JumpGame {/*** 一、回溯法*/public static boolean jumpGameBacktracking(int[] numbers) {return helper(numbers, 0);}private static boolean helper(int[] numbers, int startIndex) {if (startIndex == numbers.length - 1) {// 退出条件,到达最后一个indexreturn true;}// check the longest jump we could make from current position// Math.min(jump is within array, jump goes beyond array)// 找到跳一步的极限,相当于剪枝,把超过步长的去掉int maxJumpLength = Math.min(numbers[startIndex], numbers.length - 1 - startIndex);// start to jump from startIndex,and see whether any jump is successful and has reached the end of the arrayfor (int i = maxJumpLength; i > 0; i--) {int nextIndex = startIndex + 1;// path.add(nextIndex); 应该helper函数无返回值的时候用path有用if (helper(numbers, startIndex + 1)) {return true;}// path.remove(path.size() - 1); 为了把走过的路回退,回到初始状态好进行下一次循环}return false;}/*** Top-Down自顶向下的动态规划,相当于优化过的回溯法* 题眼在于,只要我们确定了一个index是good or bad,那么结果就不会改变* 所以就可以把index的结果存起来不用每次都去重复计算* memorization:用一个数组记录每个index是good or bad,status:[GOOD, BAD, UNKNOWN]*/public static boolean jumpGameTopDown(int[] numbers) {int[] cellsGoodNess = new int[numbers.length];Arrays.fill(cellsGoodNess, 1);return topDownHelper(numbers, 0, new ArrayList<Integer>(), cellsGoodNess);}private static boolean topDownHelper(int[] numbers, int startIndex, List<Integer> path, int[] cellsGoodNess) {if (startIndex == numbers.length - 1) {return true;}int maxJumpLength = Math.min(numbers[startIndex], numbers.length - 1 - startIndex);for (int i = maxJumpLength; i > 0; i--) {int nextIndex = startIndex + i;if (cellsGoodNess[nextIndex] != 0) {path.add(nextIndex);if (topDownHelper(numbers, startIndex + 1, path, cellsGoodNess)) {return true;}path.remove(path.size() - 1);cellsGoodNess[nextIndex] = 0;}}return false;}/*** Bottom-Up 自底向上相比较自顶向下少了回溯的部分,省去了方法栈的多次调用* The observation to make here is that we only ever jump to the right.* This means that if we start from the right of the array,* every time we will query a position to our right, that position has already be determined as being GOOD or BAD.* This means we don't need to recurse anymore, as we will always hit the memo table.*/public static boolean jumpGameBottomUp(int[] numbers) {int[] cellsGoodness = new int[numbers.length];Arrays.fill(cellsGoodness, 0);// 将最后一个元素赋值为1cellsGoodness[numbers.length - 1] = 1;// 从右到左遍历数组for (int i = numbers.length - 2; i >= 0; i--) {int maxJumpLength = Math.min(numbers[i], numbers.length - 1 - i);for (int jumpLength = maxJumpLength; jumpLength > 0; jumpLength--) {int nextIndex = i + jumpLength;if (cellsGoodness[nextIndex] == 1) {// 如果后一个注定可以到达最后一个index,那么当前可以到nextIndex的i就也可以到达cellsGoodness[i] = 1;break;}}}// 最后的返回就是看第一个index的memo是否为true了return cellsGoodness[0] == 1;}/*** 贪心* Once we have our code in the bottom-up state, we can make one final, important observation.* From a given position, when we try to see if we can jump to a GOOD position, we only ever use one - the first one.* In other words, the left-most one.* If we keep track of this left-most GOOD position as a separate variable, we can avoid searching for it in the array.* Not only that, but we can stop using the array altogether.*/public static boolean jumpGameGreedy(int[] numbers) {int leftGoodPosition = numbers.length - 1;// 从右到左遍历for (int i = numbers.length - 2; i >= 0; i--) {// 如果可以从一个当前position到达good cell,那么当前position一定是goodint maxCurrentJumpLength = i + numbers[i];if (maxCurrentJumpLength >= leftGoodPosition) {// 当前位置经过当前最长步长能到达leftGoodPosition = i;}}// 判定最后的最后,leftGoodPosition是否为最左边的indexreturn leftGoodPosition == 0;}public static void main(String[] args) {int[] trueNumbers = new int[]{2,3,1,1,4};int[] falseNumbers = new int[]{3,2,1,0,4};System.out.println("jumpGameBacktracking true result:" + jumpGameBacktracking(trueNumbers));System.out.println("jumpGameBacktracking false result:" + jumpGameBacktracking(falseNumbers));System.out.println("jumpGameTopDown true result:" + jumpGameTopDown(trueNumbers));System.out.println("jumpGameTopDown false result:" + jumpGameTopDown(falseNumbers));System.out.println("jumpGameBottomUp true result:" + jumpGameBottomUp(trueNumbers));System.out.println("jumpGameBottomUp false result:" + jumpGameBottomUp(falseNumbers));System.out.println("jumpGameGreedy true result:" + jumpGameGreedy(trueNumbers));System.out.println("jumpGameGreedy false result:" + jumpGameGreedy(falseNumbers));}
}

四种方法解决JumpGame相关推荐

  1. 四种方法解决最大连续子序列和问题

    四种方法解决最大连续子序列和问题 参考文章: (1)四种方法解决最大连续子序列和问题 (2)https://www.cnblogs.com/AlvinZH/p/6795647.html 备忘一下.

  2. 四种方法解决DIV高度自适应问题

    四种方法解决DIV高度自适应问题 参考文章: (1)四种方法解决DIV高度自适应问题 (2)https://www.cnblogs.com/smght/p/4505614.html 备忘一下.

  3. html打印为pdf表格显示不全,打印表格时内容显示不完整怎么办?四种方法解决WPS不完整问题...

    在打印表格时,偶尔出现表格内容显示不完整的状况,这是什么原因导致的呢?出现这样的情况应该如何处理?接下来为大家介绍几种处理方法,可以对应情况来解决. 一.取消打印区域 打印表格显示不完整,有可能是因为 ...

  4. html打印时显示不全,打印表格时内容显示不完整怎么办?四种方法解决WPS不完整问题...

    在打印表格时,偶尔出现表格内容显示不完整的状况,这是什么原因导致的呢?出现这样的情况应该如何处理?接下来为大家介绍几种处理方法,可以对应情况来解决. 一.取消打印区域 打印表格显示不完整,有可能是因为 ...

  5. 四种方法解决VMware Workstation pro 无法在Windows上运行(亲测有效)

    Windows更新导致VMware Workstation无法运行??? 问题: 最近微软发布的更新补丁导致许多用户的VMware Workstation无法运行.双击打开出现下图所示情况. 解决办法 ...

  6. 四种方法解决:Windows10下使用SVN文件夹不显示小绿勾

    此问题有多种解决方案,在此列出主流观点. 方法1.右键没显示小绿勾的文件夹,按照图片顺序操作 再按照图片操作 重启. 或如下图示代替重启, 结束任务 启动任务,运行新任务 方法2. 1.Win+R,输 ...

  7. 四种方法解决01背包问题

    01背包问题 01背包问题可以用dp或者dfs的方法来做 dfs的好处在于:它可以找出所有的选择方案,如果题目需要找方案的个数或者输出所有方案,就只能够选择dfs,而如果是用来输出最值,那么还是dp好 ...

  8. 【POJ - 2533】Longest Ordered Subsequence(四种方法解决最长上升子序列 含二分优化版本)

    题干: Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 41944   Accepted: 18453 Description ...

  9. 解决跨域请求的四种方法

    跨域 跨域就是请求的url中的"协议"."域名"."端口号"其中任何一种不一样都是属于跨域.解决跨域的主要的四种方法是jsonp.跨域资源共 ...

  10. 下载Word文档的四种方法

    http://www.cnblogs.com/zjyuan/archive/2011/02/14/1954009.html //第一种方法: Response.ClearContent(); Resp ...

最新文章

  1. 这三个普通程序员,几个月就成功转型AI,他们的经验是...
  2. 新建域用户添加提示密码策略受限
  3. 多模型不仅是不同的初始化值会得到不同状态(多态微调结构网络)
  4. golang 得到 结构体 struct 标签 tag 内容 结构体中的``数据
  5. 深入理解C代码中的注释
  6. php mysql建表_mysql建表测试
  7. C语言不调用库函数画一个三角形
  8. java 单例方法_Java-单例模式 - 惊觉
  9. 如何查看文件的字符集
  10. day7 java的封装
  11. while语句,do-while与for循环的介绍
  12. vue限制点击次数_vue点击切换颜色限制个数(用了mui框架)
  13. OpenCV 3.0 CvMat and cv::Mat Conversion
  14. 记录一下安装eclipse中的windows-builder组件时的一些问题
  15. linux用管理员给用户权限,Linux普通用户获得管理员权限
  16. html 获取浏览器宽高,js获取浏览器高度与宽度的方法
  17. UOJ275 [清华集训2016] 组合数问题 【Lucas定理】【数位DP】
  18. CAN通讯程序C语言,AT90CAN单片机CAN通信模块介绍及软件编程
  19. OSI七层模型和STP/IP协议模型(生动形象,简单易懂)
  20. lstm中look_back的大小选择_基于时空关联度加权的LSTM短时交通速度预测

热门文章

  1. 四旋翼飞行器数学模型
  2. 微博、微信朋友圈、QQ空间功能对比
  3. 【VBA研究】调用API实现汉字简繁互换
  4. AI资源对接需求汇总: 第4期
  5. 第三阶段应用层——1.5 数码相册—使用FreeType在LCD上显示单个字符
  6. python数字转unicode_python2.7响应数据中unicode转中文
  7. 兆比特每秒和兆字节每秒_Mbps和MB/S一样吗?我们平时经常说的多少M带宽是哪个?...
  8. NRF52832 SDK 14.0.0设置内部32768
  9. 服务器usb驱动安装系统安装失败怎么办,USB3.0驱动无法安装失败怎么办?USB驱动失败失败的解决方法...
  10. 创建你的战略型人际网络