LeetCode55
跳跃游戏1:
https://leetcode-cn.com/problems/jump-game/
从前往后:
对于每个能够到达的位置选取最大值,最后如果最大值能够到达数组长度
初始值,数组在0位置,只能到达0位置。
public class Solution {
public boolean canJump(int[] nums) {
int n = nums.length;
int rightmost = 0;
for (int i = 0; i < n; ++i) {
if (i <= rightmost) {
rightmost = Math.max(rightmost, i + nums[i]);
if (rightmost >= n - 1) {
return true;
}
}
}
return false;
}
}
从后往前:
大致思路一样:
设置一个变量值position,表示当前节点距离目标节点的距离:
如果arr[i]<position,position++
如果大于等于position,则position重置为1
class Solution {
public boolean canJump(int[] nums) {
if (nums.length == 0 || nums.length == 1) return true;
int previous = nums.length - 2;
int distance = 1;
while (previous > 0) {
if (nums[previous] < distance) {
distance++;
} else {
distance = 1;
}
previous--;
}
if (nums[previous] >= distance) {
return true;
}
return false;
}
}
跳跃游戏2:
https://leetcode-cn.com/problems/jump-game-ii/
与跳跃游戏1不同的是,该问题让寻求最小跳跃步数,所以是标准的贪心问题解决套路
所以我们应该进行如下考虑
当前位置,应该考虑,下一步能够走的最远距离。
解法一 顺藤摸瓜
对于下一步而言,每次都要选取下一步跳跃步数最大的,
当然,选取区间为[当前位置,当前位置+arr[当前位置]];
当然,每次选取之后,需要更新steps++
第一步是2所以对于下一步而言,应该选取3,而不是选取1,因为对于下一步而言,3对应的跳跃步数是最大的。
同理,应该选取4。
public int jump(int[] nums) {
int end = 0;
int maxPosition = 0;
int steps = 0;
for(int i = 0; i < nums.length - 1; i++){
//找能跳的最远的
maxPosition = Math.max(maxPosition, nums[i] + i);
if( i == end){ //遇到边界,就更新边界,并且步数加一
end = maxPosition;
steps++;
}
}
return steps;
}
解法二,顺瓜摸藤
1.定义一个position,初始值为arr.length-1
2.从左到右遍历数组,找到第一个能够到达positon的位置,
3.更新position为当前位置,返回第二步,
4.结束条件为position=0
public int jump(int[] nums) {
int position = nums.length - 1; //要找的位置
int steps = 0;
while (position != 0) { //是否到了第 0 个位置
for (int i = 0; i < position; i++) {
if (nums[i] >= position - i) {
position = i; //更新要找的位置
steps++;
break;
}
}
}
return steps;
}
所以,面对这种问题,就是贪心问题,那么我们就应该进行如下考虑:
有一个边界值 = i + arr[i]
从当前位置开始遍历,到边界值结束,
从中挑选下一个最大边界值。