【问题描述】

给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个位置。示例 1:输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。

【解答思路】

1. 正向贪心

时间复杂度:O(N) 空间复杂度是O(1)

  public boolean canJump(int[] nums) {if (nums == null || nums.length == 0) return true;int maxDist = 0;int n = nums.length;for (int i = 0; i < n; i++) {// 到不了该位置,提前终止if (maxDist < i) return false;// 可以到达末尾位置,提前终止if (maxDist >= n - 1) return true;// 更新可以到达的最远距离maxDist = Math.max(maxDist, nums[i] + i); }return false;}
2. 反向贪心

以[2, 3, 1, 1, 4]为例,我们的目标是到达最后一个位置。
1、因为倒数第二个位置为1,所以从倒数第二个位置可以到达最后一个位置。因此只要我们能到达倒数第二个位置就能到达最后一个位置。
2、因为倒数第三个位置为1,所以从倒数第三个位置可以到达倒数第二个位置。因此只要我们能到达倒数第三个位置就能到达倒数第二个位置从而能到达最后一个位置。
3、因为倒数第四个位置为3,所以从倒数第四个位置可以到达倒数第三个位置。因此只要我们能到达倒数第四个位置就能到达倒数第三个位置从而能到达最后一个位置。
4、因为倒数第五个位置为2,所以从倒数第五个位置可以到达倒数第四个位置。因此只要我们能到达倒数第五个位置(也就是第一个位置)就能到达倒数第三个位置从而能到达最后一个位置。
因此,可以到达最后一个位置。

  • 用一个变量pos来表示需要到达的位置,并初始化为nums.length - 1表示需要到达的位置为最后一个位置。
  • 从nums.length - 2向前遍历,if(nums[i] + i >= pos)表示从当前位置出发能够到达pos,到达当前位置i就可以到达pos,更新pos为i的值。
  • 遍历到最后如果pos==0,也就表示从开始能够跳到末尾。

时间复杂度:O(N) 空间复杂度是O(1)

public boolean canJump(int[] nums) {if (nums == null || nums.length == 0) {return false;}//pos表示需要到达的位置int pos = nums.length - 1;for (int i = nums.length - 2; i >= 0; i--) {if (nums[i] + i >= pos) {pos = i;}}return pos == 0;}
3.动态规划

我们新建一个boolean[] dp来表示能否到达该位置。初始化dp[0]=true,此时dp为[true,false,false,false,false]。
以nums = [2, 3, 1, 1, 4]为例,
1、dp[0] = true, nums[0] = 2, 因此往后推两个位置也可到达,此时dp为[true,true,true,false,false]。
2、dp[1] = true, nums[1] = 3, 因此往后推两个位置也可到达,此时dp为[true,true,true,true,true]。
此时dp[4] = true,其实已经可以表示能到达末尾了。这种表示方法在下面的代码中用表示一
3、dp[2] = true, nums[2] = 1, 因此往后推一个位置也可到达,此时dp为[true,true,true,true,true]。
4、dp[3] = true, nums[3] = 1, 因此往后推一个位置也可到达,此时dp为[true,true,true,true,true]。
此种方式用方式二表示
时间复杂度是O(N^2),空间复杂度是O(N)

public boolean canJump1(int[] nums) {if (nums == null || nums.length == 0) {return false;}int len = nums.length;boolean[] dp = new boolean[len];dp[0] = true;for (int i = 0; i < len - 1; i++) {if (dp[i]) {for (int j = i; j < len && j <= i + nums[i]; j++) {dp[j] = true;}}if (dp[len - 1]) {return true;}}return dp[len - 1];}public boolean canJump2(int[] nums) {if (nums == null || nums.length == 0) {return false;}int len = nums.length;boolean[] dp = new boolean[len];dp[0] = true;for (int i = 0; i < len - 1; i++) {if (dp[i]) {for (int j = i; j < len && j <= i + nums[i]; j++) {dp[j] = true;}}}return dp[len - 1];}

【总结】

1. 动态or贪心

-如果使用动态规划,dp[i]代表能否跳到第i个格子的话,那么dp[i]本身没有办法很好地从dp[j](j < i)中得到,因为不知道有哪些格子可以跳到该点,因此动态规划的解法可能就没有那么优了。
-如果使用贪心(贪心是每个状态只使用一次的动态规划),是因为判断一个格子是否能到达,其实只要看这个格子是否在当前的可到达的区间内即可——而维护一个区间要比维护一个dp数组简单得多,况且区间的左端必然是0,那么只需要维护右端即可了~

2.思路方向找准 块状思考 边界终止条件多样化 想好再下手
3.Missing return statement” within if / for / while

if, while 或 for 里面的return 有可能不执行,编译器将强制您添加return语句
除非使用if-else结构

if(condition){return;
}
else{return;
}

参考链接:https://leetcode-cn.com/problems/jump-game/solution/shun-zhao-tui-dao-zhao-tui-liang-chong-fang-shi-ji/

[Leedcode][JAVA][第55题][跳跃游戏][贪心][动态规划]相关推荐

  1. [Leedcode][JAVA][第45题][跳跃游戏 II][贪心算法]

    [问题描述][Leedcode][JAVA][第45题][跳跃游戏 II] 输入: [2,3,1,1,4] 输出: 2 解释: 跳到最后一个位置的最小跳跃数是 2.从下标为 0 跳到下标为 1 的位置 ...

  2. 《LeetCode力扣练习》第55题 跳跃游戏 Java

    <LeetCode力扣练习>第55题 跳跃游戏 Java 一.资源 题目: 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 . 数组中的每个元素代表你在该位置可以跳跃的最大 ...

  3. 跳格子问题(LeetCode第55题 跳跃游戏)平民解

    目录 三种思路 1.动态规划(结果超时) 2.贪心法 3.换一种思路 三种思路 1.动态规划(结果超时) 时间复杂度为o(n^2) def canJump(self, nums):"&quo ...

  4. [Leedcode][JAVA][第289题][生命游戏]

    [问题描述] 根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机.给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞.每个细胞都具 ...

  5. [Leedcode][JAVA][第837题][新21点][动态规划][数学]

    [问题描述][中等] 爱丽丝参与一个大致基于纸牌游戏 "21点" 规则的游戏,描述如下:爱丽丝以 0 分开始,并在她的得分少于 K 分时抽取数字. 抽取时,她从 [1, W] 的范 ...

  6. LeetCode55跳跃游戏//力扣55跳跃游戏(贪心)

    LeetCode55跳跃游戏//力扣55跳跃游戏(贪心) 来源:力扣(LeetCode) 链接:题目跳转 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 . 数组中的每个元素代表你在该 ...

  7. [Leedcode][JAVA][第105题][从前序与中序遍历序列构造二叉树][栈][递归][二叉树]

    [问题描述][中等] 根据一棵树的前序遍历与中序遍历构造二叉树.注意: 你可以假设树中没有重复的元素.例如,给出前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = ...

  8. [Leedcode][JAVA][第470题][Ran7()实现Rand10()]

    [问题描述][Leedcode][JAVA][第470题][Ran7()实现Rand10()] 已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 ...

  9. 跳跃游戏 (动态规划剪枝/前缀和/滑动窗口/BFS剪枝)

    一.跳跃游戏简单介绍 1. 跳跃游戏简单介绍 跳跃游戏是一种典型的算法题目,经常是给定一数组arr,从数组的某一位置i出发,根据一定的跳跃规则,比如从i位置能跳arr[i]步,或者小于arr[i]步, ...

最新文章

  1. jgit查询远程仓库_JAVA 使用jgit管理git仓库
  2. 华为诺亚方舟实验室主任李航:神经符号处理开启自然语言处理新篇章
  3. 业界首个机密计算容器运行时—Inclavare Containers正式进入CNCF!
  4. N皇后问题12 · N-Queens
  5. java的核心类库_Java核心类库,集合框架
  6. xp环境下 .net framework 3.5 安装过程过慢 原因浅析
  7. html模仿登陆页面,登陆注册页面html代码(仿知乎)
  8. wget下载太慢问题
  9. 编译原理递归下降语法分析器C++实现
  10. 【C++】《C++ Primer Plus》--复习题、编程练习题答案
  11. Linux网络操作系统及应用教程( 项目式)项目一
  12. 高级计算机程序员实操题,国家计算机软考高级程序员历年真题1990.doc
  13. 做了一款DTU,网络通信模块化,代码开源,可以二次开发
  14. 一些货币政策及金融术语简介
  15. python123新版个人所得税计算请输入正数_Python训练的数字组合,个人所得税计算,完全平方数,python,之...
  16. 力扣刷题 DAY_61 回溯
  17. IllegalReferenceCountException: refCnt: 0, decrement: 1
  18. android 首字母 验证码,Android 验证码功能实现代码
  19. python办公自动化(4)拆分表格
  20. CAS 单点登录/登出 系统

热门文章

  1. Spring 4 官方文档学习(十)数据访问之JDBC
  2. 为什么objc_msgSend必须用汇编实现
  3. .net core linux安装
  4. c# mysql executenonquery_C#中ExecuteNonQuery()返回值注意点分析
  5. IO流的体系及FileReader、FileWriter
  6. 创建接口匿名实现类的对象的四种方法
  7. (JAVA)String类之比较方法(2)
  8. (JAVA)Object类之Scanner
  9. html表单不允许修改,[问题]如何在表单里定义(form)仅仅可读,不可修改的列?
  10. 研发中会使用到的工具