Create 55. Jump Game.md

This commit is contained in:
唐树森 2019-01-17 23:27:55 +08:00 committed by GitHub
parent 46cdd5b251
commit 73701020a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -0,0 +1,56 @@
# [55. Jump Game](https://leetcode.com/problems/jump-game/)
# 思路
给定一个非负数组成的数组,每个元素代表从当前位置能向前跳的最大步数,初始位置为第一个元素,问能否到达最后一个元素。
## 思路一、动态规划
开辟一个和nums同样大小的数组can_reach其代表的意思是: 若`can_reach[i]==1`说明从位置i可以到达最后一个位置若`can_reach[i]==0`则说明不能到达。
所以最后的返回结果就是`can_reach[0]`。
那我们该怎样求`can_reach[i]`呢? 我们知道从位置i能到达的最远位置是`i+nums[i]`,所以我们只需要看在这个区间内是否有满足能到达的就可以了,即若存在
j属于[i+1, i+nums[i]],使得`can_reach[j]`为1那么`can_reach[i]=1`,否则`can_reach[i]=0`。
所以我们应该从后往前算can_reach。
若nums中所有元素都为0则是最坏情况此时得出时间复杂度为O(n^2)空间复杂度为O(n)。
## 思路二、贪心
思路一的时间复杂度比较高,仔细分析题目可得出更快的解法。
其实我们用贪心就可以解决此问题从后往前遍历数组nums用d记录直到此时能到达的最远的位置。假设此时遍历到了位置i如果出现了`d < i`说明根本到达不了位置i更别说到达
最后一个位置了所以直接返回false即可若`d >= n - 1`说明此时就可以到达最后一个位置了所以直接返回true即可否则更新d: `d = max(d, i + nums[i])`
这种方法最多只遍历了一遍数组所以时间复杂度为O(n)空间复杂度显然为O(1)。
# C++
## 思路一
``` C++
class Solution {
public:
bool canJump(vector<int>& nums){
int n = nums.size();
int can_reach[n] = {0};
can_reach[n - 1] = 1;
for(int i = n - 2; i >= 0; i--)
for(int j = 1; j <= nums[i]; j++)
if(can_reach[i + j]){
can_reach[i] = 1;
break;
}
return can_reach[0] == 1;
}
};
```
## 思路二
``` C++
class Solution {
public:
bool canJump(vector<int>& nums){
int n = nums.size();
int d = 0;
for(int i = 0; i < n; i++){
if(d < i) return false;
if(d >= n - 1) return true;
d = max(d, i + nums[i]);
}
return false;
}
};
```