数组跳跃游戏 Jump Game
2013-11-29 19:22
399 查看
题目源自于leetcode。
题目: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.
For example:
A = [2,3,1,1,4], return true.
A = [3,2,1,0,4], return false.
思路一:依靠题目的规则循规蹈矩。
解题的一个重要思想是想到各种极端情况,考虑周全。
数组中的数都是非负整数,所以如果数组内没有0的话,一定是从开始能跳到最后的。如果有0的话,必须有办法跳到0的右边去。
极端的一个情况是这样的,543210...那么怎么也跳不到0右面。所以至少需要0的左边有个数的大于它到0的距离。
刚才只考虑了单独1个0,对于连续的多个0,就需要其左边的某个数大于到最右的0的距离。
另外,不管最后一个数是什么,只要到达它即可,所以我的首个研究对象应该是倒数第二个数。
解决步骤:根据这个思路,我对数组从右向左遍历。当遇到0或0s时,就开始判断其左边是否存在值大于到最右0的距离的数。当再次遇到0或0s时,若没有找到这样的数,则宣布失败(无法完成跳跃);若有这样的数,重新开始下一轮判断。该方法时间复杂度为O(N)。
注意每个while遍历的都应该做超出边界值的检查。
思路二:贪心法。记录一个变量保持最远可达的位置。从左到右遍历时,不断刷新这个最远距离。
题目: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.
For example:
A = [2,3,1,1,4], return true.
A = [3,2,1,0,4], return false.
思路一:依靠题目的规则循规蹈矩。
解题的一个重要思想是想到各种极端情况,考虑周全。
数组中的数都是非负整数,所以如果数组内没有0的话,一定是从开始能跳到最后的。如果有0的话,必须有办法跳到0的右边去。
极端的一个情况是这样的,543210...那么怎么也跳不到0右面。所以至少需要0的左边有个数的大于它到0的距离。
刚才只考虑了单独1个0,对于连续的多个0,就需要其左边的某个数大于到最右的0的距离。
另外,不管最后一个数是什么,只要到达它即可,所以我的首个研究对象应该是倒数第二个数。
解决步骤:根据这个思路,我对数组从右向左遍历。当遇到0或0s时,就开始判断其左边是否存在值大于到最右0的距离的数。当再次遇到0或0s时,若没有找到这样的数,则宣布失败(无法完成跳跃);若有这样的数,重新开始下一轮判断。该方法时间复杂度为O(N)。
注意每个while遍历的都应该做超出边界值的检查。
class Solution { public: bool canJump(int A[], int n) { if(A == NULL || n <= 0) return false; int i = n-2; int idx_0; int flag; while(i >= 0) { if(A[i] == 0) { flag = 0; idx_0 = i; i--; while(i >=0 && A[i] == 0) i--; while(i >=0 && A[i] != 0) { if(A[i] > idx_0 - i) flag = 1; i--; } if(flag == 0) return false; else continue; } i--; } return true; } };
思路二:贪心法。记录一个变量保持最远可达的位置。从左到右遍历时,不断刷新这个最远距离。
class Solution { public: bool canJump(int A[], int n) { int reach = 1; for(int i=0;i<reach && reach < n;i++) reach = max(reach, i + 1 + A[i]); return reach >= n; } };思路三:动态规划法。不过在此就没必要了,空间复杂度太高。
class Solution { public: bool canJump(int A[], int n) { vector<int> v(n, 0); for(int i=1;i<n;i++) { v[i] = max(v[i-1], A[i-1]) - 1; //状态递推 if(v[i] < 0) return false; } return v[n-1] >= 0; } };
相关文章推荐
- flex显示数据库表中的所有数据
- 第14周项目7-成绩处理函数版
- select元素添加option的add()方法 | try{}catch{}
- IOS下获取文件夹下的内容
- SDWebImage的block使用
- 使用GRC Any Blocks
- 安卓之多线程请求数据
- HDU4678_Mine
- hdu 2686 最小费用最大流
- MyBatis中出现Mapped Statements collection does not contain value
- 最经发现C盘空间只有3.5M了,原来自己没有关休眠
- hdu 2686 最小费用最大流
- hdu 1429(bfs+状态压缩)
- 理解ObjC下的ARC
- Linux下如何得到本机所有IP地址及MAC地址
- oracle:ORACLE 实际返回的行数超出请求的行数
- UISlide属性介绍
- 词法分析器
- git 笔记记录(七) git Clone
- 《白手起家Win32SDK应用程序》(完整版+目录)