问题描述
You are given an integer array
nums
. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position.Return
true
if you can reach the last index, orfalse
otherwise解释:
给定一个数字nums,你被放在第一个位置上,nums中的每一个元素代表你处于该位置最多可以跳几步。
如果能跳到最后一个位置,返回true;否则返回false
案例
Input: nums = [2,3,1,1,4] Output: true Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.\ 解释: 第一个位置跳1步道第二个位置,第二个位置跳3步到最后一个位置
基本思想-1
设nums的大小为size,构建长度为size的数组dp。
- dp[i] 表示的是
nums[0~i-1]
有多少种方法可以跳至i位置,则dp[i] 的更新依赖于nums[0~i-1]
, 具体如下:- 假设
0<=j <=i-1
, 如果 nums[j] + j >= i,那么说明由j位置可以跳到i,此时 dp[i] = dp[j] ,因为可能存在多个满足上述条件的j,所以 公式修改为 dp[i] = dp[j] + dp[i]
- 假设
时间复杂度\(o(n^2)\)
代码实现如下
def canJump(self, nums: List[int]) -> bool:
size = len(nums)
if size <=1 : return True
dp = [0] * size
dp[0] = 1 # dp[i] 跳到第i个位置的方法数目
for i in range(1,size):
for j in range(0,i):
if (nums[j] > 0) and (dp[j] > 0) and ((nums[j] + j ) >= i):
dp[i] = dp[i] + dp[j]
return dp[size-1]>0
上述代码报错,提示 Time Limit Exceeded
,测试用例明显数组太大了,时间复杂度太高了
优化
记录0~i-1最多能跳到那个位置x,
对于位置i,只需要判断i位置是否能到达 & i位置是否可以继续跳。
当i<=x ,表示i位置可以跳到。知道进行到倒数第二个位置,此时 0~size-1的最大能跳跃位置是x,如果\(x >= size-1\), 则表示可以跳到最终位置,否则表示不能跳到
代码
C++
bool canJump(vector<int>& nums) {
int size = nums.size();
if (size<=1) return true;
if (nums[0]<=0) return false;
int maxLoc = nums[0];
int maxLocIndex = 0;
for(int i=1;i<(size-1);++i) {
if (nums[i]<=0 || i > maxLoc) continue; // 如果i位置达不到 或者 i位置没办法跳跃
if ((nums[i]+i) >= maxLoc) {
maxLoc = nums[i] + i;
maxLocIndex = i;
}
}
return (size-1) <= maxLoc;
}
标签:index,nums,55,位置,maxLoc,jump,Game,dp,size
From: https://www.cnblogs.com/douniwanli/p/18187375