小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
下个月要参加一个比赛,想来还是在动态规划的题目上可以再多联系一些,所以在leetcode找到了相关题集,每天做一些,希望下个月的比赛能带领队友走向胜利而不是团灭吧。
题目
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。
示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。
思路
前两天刚做过一题差不多的。 题目要求的是,能否达到最后一个目标,我们顺着考虑,就是从当前位置出发,可以到达哪些位置,把这些位置标记为可达,然后从可达的位置出发,可能达到哪些新位置,如果所有的可达位置都遍历完成后,不能包含最后一点点,那就是不可达,如果包含,那就是可达。当然,在遍历的过程中发现已经包含了最后一个点,那也不用再傻傻遍历完。 模拟一下示例1:我们初始在下标0的位置,目前可达的点只有0,它的值是2,这样我们的可达点就是[0,2],因为0已经遍历过了,我们接下来遍历1和2,遍历1之后,可达2、3、4,已经包含4,所以肯定是可达的。
Java版本代码
class Solution {
public boolean canJump(int[] nums) {
int len = nums.length;
int index = 0;
int start = index + 1;
int end = index + nums[0];
while (end < len - 1) {
if (end < start) {
break;
}
int max = end;
for (int i = start; i <= end; i++) {
if (i + nums[i] > max) {
max = i + nums[i];
}
}
// start 更新成下一次开始遍历的点,因为0-end已经遍历过了,下一次要遍历的点至少是end+1
start = end + 1;
// end 更新成下一次能跳到的最远的点
end = max;
}
if (end >= len - 1) {
return true;
} else {
return false;
}
}
}