LeetCode Jump Game
2015-06-28 12:19
260 查看
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.
Solution:
Firstly, we may easily want to solve this problem with BFS or DFS. But using a system stack will cause stack overflow, and BFS may be easier to code.
A list like LinkedList can be used as queue, which stores all the tokens that are to be operated.
For each token in queue:
if it has been operated, vis[i] = true, then skip it.
else if this token+nums[token] is equal or greater than the last index of array, then return true.
else for each index within the range [ token+1, token+nums[token] ), add them into the queue.
until the queue is empty.
However we get a TLE with BFS, so another method is required.
Let us explore this array again. All the integers are non-negative, so for all the number that is greater than zero, it can continue to 'go on' to its next number. From this point, we may find the new method: find whether there
is a gap in the nums[] array, if so then return false, else return true.
How to find a gap:
we can tell from the examples the feature of such 'false' array: 4 3 2 1 0.
--- every time we find a zero, we can scan the index from token to zero; for each index i, if i+nums[i] > tot then continue the big loop, if no 'continue loop;' here, that is to say we can go to the end of the inner loop, then
it means there exits a gap marked by zero in the array, so return false.
Pay attention that although there are two for loop, actually it is equal to one for loop. The time complexity is still O(n).
最后再多说一下, 因为网上看了很多题解,有部分是错误的。另一种可行的方法是一维动态规划+线性扫描。这个做法是在遍历的同时维护一个max值,记录能够达到的最远距离。同样是看这个max值在遇到0值的时候能否越过这个0,也就是我这个方法所说的‘gap’。
两个方法,一种是线性扫描,在线,复杂度为O(n);另外一种是如上代码一样,以0为分割点,其实可以离线做,现在这样在线处理理论上复杂度不变,复杂度也是O(n)。
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.
Solution:
Firstly, we may easily want to solve this problem with BFS or DFS. But using a system stack will cause stack overflow, and BFS may be easier to code.
A list like LinkedList can be used as queue, which stores all the tokens that are to be operated.
For each token in queue:
if it has been operated, vis[i] = true, then skip it.
else if this token+nums[token] is equal or greater than the last index of array, then return true.
else for each index within the range [ token+1, token+nums[token] ), add them into the queue.
until the queue is empty.
However we get a TLE with BFS, so another method is required.
Let us explore this array again. All the integers are non-negative, so for all the number that is greater than zero, it can continue to 'go on' to its next number. From this point, we may find the new method: find whether there
is a gap in the nums[] array, if so then return false, else return true.
How to find a gap:
we can tell from the examples the feature of such 'false' array: 4 3 2 1 0.
--- every time we find a zero, we can scan the index from token to zero; for each index i, if i+nums[i] > tot then continue the big loop, if no 'continue loop;' here, that is to say we can go to the end of the inner loop, then
it means there exits a gap marked by zero in the array, so return false.
Pay attention that although there are two for loop, actually it is equal to one for loop. The time complexity is still O(n).
import java.util.*; public class Solution { boolean vis[]; public boolean canJump(int[] nums) { if (isBlockedZero(nums)) return false; return true; // vis = new boolean[nums.length]; // return bfs(nums, 0); } boolean isBlockedZero(int nums[]) { loop: for (int i = 0; i < nums.length - 1; i++) { if (nums[i] == 0) { for (int j = i - 1; j >= 0; j--) { if (j + nums[j] > i) continue loop; } return true; } } return false; } boolean bfs(int[] nums, int tot) { LinkedList<Integer> queue = new LinkedList<Integer>(); queue.add(0); int u, r; while (!queue.isEmpty()) { u = queue.poll(); // System.out.println(u); if (u + nums[u] >= nums.length - 1) return true; if (vis[u]) continue; vis[u] = true; r = Math.min(nums.length - 1, u + nums[u]); for (int i = u + 1; i <= r; i++) { if (vis[i]) continue; queue.add(i); } } return false; } }
最后再多说一下, 因为网上看了很多题解,有部分是错误的。另一种可行的方法是一维动态规划+线性扫描。这个做法是在遍历的同时维护一个max值,记录能够达到的最远距离。同样是看这个max值在遇到0值的时候能否越过这个0,也就是我这个方法所说的‘gap’。
两个方法,一种是线性扫描,在线,复杂度为O(n);另外一种是如上代码一样,以0为分割点,其实可以离线做,现在这样在线处理理论上复杂度不变,复杂度也是O(n)。
相关文章推荐
- What qualities characterize a great PhD student
- '\r'与'\n'的区别
- shell脚本:猜数字游戏
- shell脚本:猜数字游戏
- python实现搜索指定目录下文件及文件内搜索指定关键词的方法
- LeetCode Spiral Matrix
- tortoiseSVN svn+ssh
- 想搭建自己的网站,应该从哪处入手呢?选择什么样配置的服务器捏?通过哪些手段赚取足够的维护网
- Unity 脚本优化
- 分析用Python脚本关闭文件操作的机制
- GCC系列: Homebrew安装GCC和binutils
- Double-Checked Locking is Fixed In C++11
- Mysql的limit用法
- nodejs学习过程的问题
- 关于搜狐新浪ip库查询接口的使用
- 关于 android 环信无法正确获取昵称的问题
- windows与OSX双操的时区-黑苹果之路
- LinkedList浅析
- 倾斜摄影技术发展与应用前景
- android 数据库查询方法