Jump Game
题目55:Jump Game I
题目描述:
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.
解法
思路分析1:贪心算法
只需要判断是否能从start走到end,所以判断能走到的下标及其能走到的最远距离,如果最远距离大于等于数组长度,则可以走到,返回true,否则返回false。
bool CanJump(vector<int> nums) {
int len = nums.size();
if (len == 0)
return true;
int maxi = 0;
/*
* maxi记录的是上一个下标能走到的最远下标
* i <= maxi是判断能否走到下标i,如果不能循环结束
*/
for (int i = 0; i <= maxi && i < len; i ++)
maxi = max(maxi, nums[i] + i);
if (maxi >= len - 1)
return true;
else
return false;
}
/* 更好理解一些 */
bool CanJump(vector<int> nums) {
int len = nums.size();
if (len == 0)
return true;
int remain = nums[0];
for (i = 1; i < len; i ++) {
-- remain;
if (remain < 0)
return false;
if (remain < nums[i])
remain = nums[i];
}
return true;
}
思路分析2:动态规划
dp[i]表示从下标0走到下标i时剩余的最大步数。
dp[0] = 0;
dp[i] = max(dp[i - 1], nums[i - 1]) - 1;
如果dp[i] < 0,则表示不能走到,返回false。
bool CanJump(vector<int> nums) {
int len = nums.size();
if (len == 0)
return true;
vector<int> dp(len);
dp[0] = 0;
for (int i = 1; i < len; i ++) {
dp[i] = max(dp[i - 1], nums[i - 1]) - 1;
/* 为什么是<0,而不是==0,因为==0是表示刚好走到这 */
if (dp[i] < 0)
return false;
}
return dp[len - 1] >= 0;
}
改进版,不用保存dp[i],就用贪心。
题目45:Jump Game II
题目描述:
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.
Your goal is to reach the last index in the minimum number of jumps.
For example:
Given array A = [2,3,1,1,4]
The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)
思路分析:
贪心算法,记录当前能到达的最远位置cur,下次能到达的最远位置next,记录步数step,如果cur == len - 1,则返回step。
容易的理解:维护一个区间,区间表示第i步能到达的范围。每次都遍历一遍当前区间内的所有元素,从一个元素出发的最远可达距离是i + nums[i],那么下一个区间的左端点就是当前区间的右端点+1,下一个区间的右端点就是当前区间的max(next, nums[i] + 1),依次类推,直到区间包含了终点,统计当前步数即可。
int Jump(vector<int> nums) {
int len = nums.size();
if (len == 0)
return 0;
int cur = 0;
int next = 0;
int step = 0;
for (int i = 0; i < len;) {
if (cur >= len - 1)
break;
while (i <= cur) {
next = max(next, nums[i] + i);
++ i;
}
++ step;
cur = next;
}
return step;
}
参考:
[1] http://fisherlei.blogspot.com/2012/12/leetcode-jump-game.html
[2]https://siddontang.gitbooks.io/leetcodesolution/content/greedy/jump_game.html
[3] http://segmentfault.com/a/1190000002651263