LintCode Jump Game 跳跃游戏
来源:互联网 发布:淘宝店不刷信誉可以吗 编辑:程序博客网 时间:2024/05/21 22:21
跳跃游戏
给出一个非负整数数组,你最初定位在数组的第一个位置。
数组中的每个元素代表你在那个位置可以跳跃的最大长度。
判断你是否能到达数组的最后一个位置。
样例
A = [2,3,1,1,4],返回 true.
A = [3,2,1,0,4],返回 false.
注意
这个问题有两个方法,一个是贪心和 动态规划。
贪心方法时间复杂度为O(N)。
动态规划方法的时间复杂度为为O(n^2)。
我们手动设置小型数据集,使大家阔以通过测试的两种方式。这仅仅是为了让大家学会如何使用动态规划的方式解决此问题。如果您用动态规划的方式完成它,你可以尝试贪心法,以使其再次通过一次。
Solution:
方法一.动态规划求解
首先来看一下如何使用动态规划求解该问题。使用动态规划求解问题,首先需要找到问题的状态和状态转化方程
假设问题的状态,假设位置
对于数组A = [2,3,1,1,4], 则有:
i = 0, dp[0] = A[0] + 0 = 2
i = 1, if dp[i-1] = dp[0]
i = 2, if dp[i-1] = dp[1]
基于上面的分析,其状态转换方程为:
注意:需要判断能否到达第
public static boolean canJumpDP(int [] A) { if (A.length == 1) return true; int [] dp = new int[A.length]; dp[0] = A[0]; for (int i = 1; i < dp.length; ++i) { if (dp[i-1] >= i) dp[i] = max(A[i]+i, dp[i-1]); else dp[i] = 0; } return dp[dp.length-1] >= A.length-1;}
方法二:贪心算法
如果对上面的代码认真分析以下的话,是没有必要创建dp数组的,可以使用一个变量来进行替换。及
public boolean canJump(int[] A) { int currMaxStep = A[0]; //当前能够跳跃的最大步数 int step = 0; for (int i = 1; i < A.length; ++i) { if (i > currMaxStep) return false; currMaxStep = max(i+A[i], currMaxStep); if (currMaxStep >= A.length-1) return true; } return currMaxStep >= A.length-1;}
跳跃游戏 II
给出一个非负整数数组,你最初定位在数组的第一个位置。
数组中的每个元素代表你在那个位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
样例
给出数组A = [2,3,1,1,4],最少到达数组最后一个位置的跳跃次数是2(从数组下标0跳一步到数组下标1,然后跳3步到数组的最后一个位置,一共跳跃2次)
方法一:动态规划求解
首先,假设问题的状态:“假设跳到数组第
对于数组 A = [2,3,1,1,4], 有:
因此,转态转换方程为:
Talk is cheap, show me the code !
/*** @param A: A list of lists of integers* @return: An integer*/public int jump(int[] A) { // write your code here int [] dp = new int[A.length]; Arrays.fill(dp, A.length); //初始化 dp[0] = 0; for (int i = 1; i < dp.length; ++i) { for (int j = 0; j < i; ++j) { if (A[j] + j >= i) dp[i] = min(dp[i], dp[j]+1); } } return dp[dp.length-1];}
时间复杂度
方法二:贪心算法
如果这代码放在LeetCode上运行是会超时的。与Jump Code I 一样这题也是可以使用贪心算法来进行求解的。。 该代码和思路来自 LeetCode discuss
其主要是基于贪心的思想。假设当前(位置i)能够跳最远的范围为[curBegin, curEnd], curFarther是在[curBegin, curEnd]范围内能够跳的最远距离(位置)。一旦当前位置(i)到了curEnd, 那么就会触发一次跳跃,并且设置curEnd等于curFarthest。按照上面的步骤,直到跳跃到最后一个位置为止。其代码为:
public int jump(int [] A) { int jumps = 0; //当前已经跳跃的步数 int curEnd = 0; //当前位置能够跳跃的最远距离 int curFarthest = 0; //在[0, curEnd]范围能的位置,能够跳跃的最远距离 for (int i = 0; i < A.length-1; ++i) { curFarthest = max(curFarthest, i+A[i]); if (i == curEnd) { jumps++; curEnd = curFarthest; if (curFarthest >= A.length-1) return jumps; } } return curFarthest >= A.length-1 ? jumps : -1;}
时间复杂度
方法三: BFS
LeetCode Discuss 上提出了BFS方法
其实可以把这个为题转换为BFS问题(注:如果认真思考一下的话, 可以看成单源最短路径问题)。及第
代码为:
public int jumpBFS(int [] A) { if (A.length < 2) return 0; int level = 0, i = 0; int currentMax=0; //当前层能够到达的最远位置 int nextMax=0; //下一层能够到达的最大位置 while (currentMax - i + 1 > 0) { level++; for (; i <= currentMax; ++i) { nextMax = max(nextMax, A[i]+i); if (nextMax >= A.length -1) return level; } currentMax = nextMax; } return 0;}
时间复杂度
- LintCode Jump Game 跳跃游戏
- [Lintcode]Jump Game跳跃游戏
- LintCode Jump Game 跳跃游戏
- [LintCode] 跳跃游戏II Jump Game II
- 数组跳跃游戏 Jump Game
- [LeetCode] Jump Game 跳跃游戏
- 55/45 Jump Game 跳跃游戏
- Jump Game 跳跃游戏(求是否能跳到最后一个) @LeetCode
- LeetCode | Jump Game II(跳跃游戏II)
- 【leetcode】Jump Game I, II 跳跃游戏一和二
- LeetCode OJ 之 Jump Game (“跳跃”游戏 - 一)
- LeetCode OJ 之 Jump Game II(“跳跃”游戏 - 二)
- leetCode 55.Jump Game(跳跃游戏) 解题思路和方法
- Leetcode #45. Jump Game II 跳跃游戏2 解题报告
- Leetcode #55. Jump Game 跳跃游戏 解题报告
- 116.Jump Game-跳跃游戏(中等题)
- 117.Jump Game II-跳跃游戏 II(中等题)
- LeetCode--------45. Jump Game II(跳跃游戏--最短路径)
- 【慕课笔记】第四章 流程控制语句 第5节 JAVA条件语句之switch
- getopt.h 头文件说明
- IO流4(IO中的其他流、编码)
- Android中的颜色
- Android Instrumention.sendPointerSync发送Event 失败源码分析
- LintCode Jump Game 跳跃游戏
- HDU 3567 - Eight II
- C++ 现代编程风格速查表
- 前端优化整理
- 数据的管理
- 插入排序
- cygwin显示设置---调用windows命令显示不正常
- Linux Java 学习记_1
- 【NYOJ】[41]三个数从小到大排序