题目地址:Jump Game
题目简介:
给定一个非负整数数组,开始位置位于数组的第一个位置。数组中每个元素代表在该位置可以跳跃的最大长度,判断是否能够达到最后一个位置。
Example 1:
Input: [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
Example 2:
Input: [3,2,1,0,4]
Output: false
Explanation:
You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.
题目分析:
1、超时的暴力递归
每到一个位置,都尽可能的把所有的可能走完。例如上面的例1中,开始位置是2,那么第一次先跳到第二个位置的3上,然后判断从该位置是否能够到最后一个位置。第二次就跳到1上,然后判断该位置是否能够到达最后一位置,如此迭代下去。
C++版:
class Solution {
public:
bool canJump(vector<int>& nums) {
if(nums.size() == 1)
return true;
else if (nums.size() != 1 && nums[0] == 0)
return false;
int first = nums[0];
for (int i = 1; i <= first; i++)
{
vector<int> temp = nums;
for (int j = 0; j < i; j++)
{
temp.erase(temp.begin());
}
if (canJump(temp))
return true;
}
return false;
}
};
2、动态规划
在当前达到的位置上,根据位置的数字,将对应能达到的位置标记为true。进行一次遍历,然后得到最终的结果。
C++版:
class Solution {
public:
bool canJump(vector<int>& nums) {
int len = nums.size();
if (len <= 1)
return true;
bool dp[len];
memset(dp, false, sizeof(dp));
dp[0] = true;
for (int i = 0; i < len - 1; i++)
{
if(dp[i])
{
int temp = nums[i];
for (int j = 1; j <= temp; j++)
{
if (i + j < len)
dp[i + j] = true;
else
break;
}
}
}
return dp[len - 1];
}
};
3、参考地址:Simple Elegant C++ | 4ms | Beats 100%
想法是查看当前位置所能达到最远的地方,如果能够达到数组长度外,那么便可以达到最后,因为这是一个范围的问题。当最大距离已经小于当前位置,说明不能达到这个位置。
C++版:
class Solution {
public:
bool canJump(vector<int>& nums) {
int maxind = 0, n = nums.size();
for(int i = 0; i < n; i++)
{
if(maxind < i)
break;
maxind = max(maxind, i + nums[i]);
if(maxind >= n - 1)
return true;
}
return false;
}
};
// 下面这句话可以加快速度,不知原理
static auto _=[](){ios::sync_with_stdio(false);return 0;}();
Python版:
class Solution:
def canJump(self, nums: List[int]) -> bool:
maxind = 0
n = len(nums)
for i in range(n):
if (maxind < i):
break
maxind = max(maxind, i + nums[i])
if (maxind >= n - 1):
return True
return False