每日一题,防止痴呆 = =
一、题目大意
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jump-game-ii
二、题目思路以及AC代码
超时思路一:
看到这题,第一个想法是dp,可能被dp折磨太久了,想法也很简单,就是dp[i]表示到达第i个位置所需要的最少步数,那么求解dp[i]的时候,就要找所有小于i的下标j,求取那些满足 j + nums[j] >= i 的 dp[j] + 1的最小值,这样的算法复杂度是O(n)的,其实就对应于官方解答的第一种思路,但是很坑的是,官方解答第一种思路用c++会超时,而用java和python不会,生无可恋 = =。
超时思路二:
然后第一个想法TLE了,我又萌生了第二个TLE的想法,就是BFS,这个状态转移也很好看出来,就是在某个位置i的时候,我可以选择跳 1 ~ nums[i] 步,那么我们只需要对这个状态进行BFS即可,当然在途中要记录那些已经走过,就没必要再走了,因为后走的步数肯定会比先走的步数长,这样的方法可能比dp的方法复杂度低一些,但总体还是O(n^2),生无可恋 = =。
正确思路三:
最后不得已,看了题解,原来是个贪心,想了一下好像也对,我们只要根据下一步的下一步能到达的最远距离来选择下一步即可,有点绕口,举个例子。
对于数组 [2, 3, 1, 1, 4],我们初始在0位置,那么下一步怎么走呢,我们可以选择走1步,或者2步,如果走1步的话,我们再下一步最远可以走到4,如果走2步的话,我们再下一步可以走到3,所以我们选择这次走1步。那为什么可以这样贪心呢?因为我只要每次保证下一步的下一步是最远的,那么就可以保证步数最少,因为这题的意思是我在 i 位置可以走小于等于nums[i]的任意步,那么就不存在贪心之后无法到达的情况,所以一定是走的越远,步数越少,而且因为每次考虑了两步,其实是包含了所有情况的。
下面给出AC代码:
为了不浪费之前写的两个TLE的思路,把代码也放在这里吧。(不知道如果改java和python会不会AC)
TLE思路一:
#define INF 2147483647
class Solution {
public:
int jump(vector<int>& nums) {
int n_size = nums.size();
int dp[n_size];
dp[0] = 0;
for (int i=1;i<n_size;i++) {
dp[i] = INF;
for (int j=0;j<i;j++) {
if (i-j <= nums[j]) {
dp[i] = min(dp[j] + 1, dp[i]);
}
}
}
return dp[n_size - 1];
}
};
TLE思路二:
class Solution {
public:
int jump(vector<int>& nums) {
int n_size = nums.size();
if (n_size <= 1) return 0;
queue<int> q;
q.push(0);
int vis[n_size];
for (int i=0;i<n_size;i++) {
vis[i] = false;
}
vis[0] = true;
int depth = 0;
bool flag = false;
while (!q.empty()) {
int q_size = q.size();
for (int i=0;i<q_size && !flag;i++) {
int cur = q.front(); q.pop();
for (int j=1;j<=nums[cur];j++) {
int next = cur + j;
if (next == n_size - 1) {
flag = true;
break;
}
if (next >= n_size) continue;
if (!vis[next]) {
vis[next] = true;
q.push(next);
}
}
}
depth++;
if (flag) break;
}
return depth;
}
};
AC代码:
class Solution {
public:
int jump(vector<int>& nums) {
int n_size = nums.size();
int maxPos = 0;
int end = 0;
int step = 0;
for (int i=0;i<n_size-1;i++) {
maxPos = max(maxPos, i + nums[i]);
if (i == end) {
end = maxPos;
step++;
}
}
return step;
}
};
如果有问题,欢迎大家指正!!!