Cover image for Interview Classic 150 Questions P55 Jump Game

Interview Classic 150 Questions P55 Jump Game


Timeline

Timeline

2025-10-02

init

Greedy, stack or queue, dynamic programming

Title:

My first thought was to use queue traversal, BFS solution, using stack should also work, but you can see this complexity is quite large.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <queue>
#include <unordered_set>
#include <vector>

using std::queue;
using std::unordered_set;
using std::vector;

class Solution {
public:
bool canJump(vector<int> &nums)
{
int n = nums.size();
int jmp;
int curr;
int i, tmp;
queue<int> que;
unordered_set<int> uset;
if (n == 1) {
return true;
}

que.push(0);
uset.insert(0);
do {
curr = que.front();
jmp = nums[curr];
if (jmp == 0) {
que.pop();
uset.erase(curr);
continue;
}

for (i = 1; i <= jmp; i++) {
tmp = curr + i;
if (tmp == n - 1) {
return true;
} else if (tmp < n && uset.count(tmp) == 0) {
que.push(tmp);
uset.insert(tmp);
}
}
uset.erase(curr);
que.pop();

} while (!que.empty());

return false;
}
};

#include <stdio.h>
int main()
{
Solution S;
vector<int> vec = { 2, 5, 0, 0 };
printf("%d\n", S.canJump(vec));
}

After reading the comments, there is an interesting solution that uses a greedy strategy. No need to think about the specific process, just jump as far as you can. If you jump past the last position, then you must be able to jump to the last position.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public:
bool canJump(vector<int>& nums) {
int i, n = nums.size();
int max_reach_pos = 0;

for( i = 0; i < n && i <= max_reach_pos; i++ ){
max_reach_pos = std::max(max_reach_pos, i + nums[i]);
}

return (max_reach_pos >= n-1);

}
};

This problem can also be solved with dynamic programming, time complexity O(n^2)

  • dp[i] = trueIndicates that i can be reached,
  • dp[i] = falseIndicates that i cannot be reached

Then for position i, if there exists j (0 <= j < i) that can be reached, and the maximum jump distance from j can cover i, that is:

1
2
3
4
5
if(j+nums[j]>=i){
dp[j] = true;
}else{
dp[j] = false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <vector>
using namespace std;

class Solution {
public:
bool canJump(vector<int>& nums) {
int n = nums.size();
vector<bool> dp(n, false);
dp[0] = true;

for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (dp[j] && j + nums[j] >= i) {
dp[i] = true;
break; // As long as it can be reached, there is no need to continue searching
}
}
}

return dp[n-1];
}
};

LeetCode Hot 100 rewrite, greedy strategy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <vector>
using std::vector;

class Solution {
public:
bool canJump(vector<int> &nums)
{
int i, n = nums.size();
int max_reach = 0;

for (i = 0; i < n && i <= max_reach; i++) {
max_reach = std::max(max_reach, i + nums[i]);
if (max_reach >= n - 1)
return true;
}

return false;
}
};