持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
跳跃游戏
给定一个非负整数数组 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 <= nums.length <= 3 * 10^4
- 0 <= nums[i] <= 10^5
解题思路
这个题目给我的第一印象有点像病毒感染的过程,从右端往左端,然后尾元素是0号病人,每个元素的值代表它的活动范围,在当前元素的活动半径内如果右侧有病人,那该元素也被传染。(那值为0的元素就是乖乖在家隔离哪都不去的小朋友了,这么一想,竟还有些可爱) 所以,第一个想法就是建立状态标签,用来标志元素的健康状态,然后从右往左扫描,更新所有元素的健康表,然后返回首元素的状态。
代码实现
class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
if (n == 1) return true;
/*创建可达标志数组,ans[n]=1表示以nums[n]为起点可以到达末尾*/
vector<bool> ans(n);
/*以pos标记当前最靠左并能到达末尾的位置,若左侧元素可达pos等价于可达末尾*/
int pos = n-1;
ans[n-1] = true;
/*倒序扫描并更新可达标志数组与pos*/
for (int i = n-2;i>=0;i--)
{
if (i+nums[i]>=pos)
{
ans[i] = true;
pos = i;
}
else
{
ans[i] = false;
}
}
/*返回可达标志数组的首位*/
return ans[0];
}
};