Skip to content

Commit a4bf8c2

Browse files
feat: add Jump Game II problem
- Greedy algorithm implementation - Multiple approaches: DP, BFS, Backtracking, Memoization - O(n) time, O(1) space complexity - Comprehensive explanations and edge cases
1 parent d432f33 commit a4bf8c2

File tree

2 files changed

+261
-0
lines changed

2 files changed

+261
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Jump Game II
2+
3+
## Problem Statement
4+
5+
You are given a 0-indexed integer array `nums` of length `n`. You are initially positioned at `nums[0]`.
6+
7+
Each element `nums[i]` represents the maximum jump length at that position.
8+
9+
Return the minimum number of jumps to reach `nums[n - 1]`. The test cases are generated such that you can reach `nums[n - 1]`.
10+
11+
## Examples
12+
13+
**Example 1:**
14+
```
15+
Input: nums = [2,3,1,1,4]
16+
Output: 2
17+
Explanation: The minimum number of jumps to reach the last index is 2. Jump 1 step from index 0 to 1, then 3 steps to the last index.
18+
```
19+
20+
## Approach
21+
22+
### Method 1: Greedy Algorithm (Recommended)
23+
1. Track the farthest position we can reach with current jumps
24+
2. Track the farthest position we can reach with next jump
25+
3. When we reach the end of current jump range, increment jump count
26+
4. Most efficient approach
27+
28+
**Time Complexity:** O(n) - Single pass
29+
**Space Complexity:** O(1) - Two variables
30+
31+
### Method 2: Dynamic Programming
32+
1. Use DP to store minimum jumps to reach each position
33+
2. dp[i] = minimum jumps to reach position i
34+
3. Less efficient than greedy approach
35+
36+
**Time Complexity:** O(n²) - Nested loops
37+
**Space Complexity:** O(n) - DP array
38+
39+
## Algorithm
40+
41+
```
42+
1. Initialize jumps = 0, currentEnd = 0, farthest = 0
43+
2. For i from 0 to n-2:
44+
a. farthest = max(farthest, i + nums[i])
45+
b. If i == currentEnd:
46+
c. jumps++
47+
d. currentEnd = farthest
48+
3. Return jumps
49+
```
50+
51+
## Key Insights
52+
53+
- **Greedy Choice**: Always try to reach the farthest position with minimum jumps
54+
- **Local Optimum**: Maximum reachable position with current jumps
55+
- **Global Optimum**: Minimum number of jumps to reach last index
56+
- **Space Optimization**: Use only two variables
57+
58+
## Alternative Approaches
59+
60+
1. **Dynamic Programming**: Use DP array
61+
2. **BFS**: Use BFS to find shortest path
62+
3. **Backtracking**: Use backtracking to explore all paths
63+
64+
## Edge Cases
65+
66+
- Single element: Return 0
67+
- Two elements: Return 1
68+
- All ones: Return n-1
69+
- Large jumps: Handle appropriately
70+
71+
## Applications
72+
73+
- Greedy algorithms
74+
- Dynamic programming patterns
75+
- Algorithm design patterns
76+
- Interview preparation
77+
- System design
78+
79+
## Optimization Opportunities
80+
81+
- **Greedy Algorithm**: Most efficient approach
82+
- **Space Optimization**: O(1) space complexity
83+
- **Single Pass**: O(n) time complexity
84+
- **No Extra Space**: Use only two variables
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/**
2+
* Time Complexity: O(n) - Single pass
3+
* Space Complexity: O(1) - Two variables
4+
*/
5+
class Solution {
6+
public int jump(int[] nums) {
7+
int jumps = 0;
8+
int currentEnd = 0;
9+
int farthest = 0;
10+
11+
for (int i = 0; i < nums.length - 1; i++) {
12+
farthest = Math.max(farthest, i + nums[i]);
13+
14+
if (i == currentEnd) {
15+
jumps++;
16+
currentEnd = farthest;
17+
}
18+
}
19+
20+
return jumps;
21+
}
22+
}
23+
24+
// Alternative approach using Dynamic Programming
25+
class SolutionDP {
26+
public int jump(int[] nums) {
27+
int[] dp = new int[nums.length];
28+
Arrays.fill(dp, Integer.MAX_VALUE);
29+
dp[0] = 0;
30+
31+
for (int i = 0; i < nums.length; i++) {
32+
for (int j = 1; j <= nums[i] && i + j < nums.length; j++) {
33+
dp[i + j] = Math.min(dp[i + j], dp[i] + 1);
34+
}
35+
}
36+
37+
return dp[nums.length - 1];
38+
}
39+
}
40+
41+
// Alternative approach using BFS
42+
class SolutionBFS {
43+
public int jump(int[] nums) {
44+
if (nums.length <= 1) {
45+
return 0;
46+
}
47+
48+
Queue<Integer> queue = new LinkedList<>();
49+
boolean[] visited = new boolean[nums.length];
50+
51+
queue.offer(0);
52+
visited[0] = true;
53+
54+
int jumps = 0;
55+
56+
while (!queue.isEmpty()) {
57+
int size = queue.size();
58+
59+
for (int i = 0; i < size; i++) {
60+
int current = queue.poll();
61+
62+
if (current == nums.length - 1) {
63+
return jumps;
64+
}
65+
66+
int farthestJump = Math.min(current + nums[current], nums.length - 1);
67+
68+
for (int next = current + 1; next <= farthestJump; next++) {
69+
if (!visited[next]) {
70+
visited[next] = true;
71+
queue.offer(next);
72+
}
73+
}
74+
}
75+
76+
jumps++;
77+
}
78+
79+
return jumps;
80+
}
81+
}
82+
83+
// Alternative approach using backtracking
84+
class SolutionBacktracking {
85+
public int jump(int[] nums) {
86+
return jumpHelper(nums, 0);
87+
}
88+
89+
private int jumpHelper(int[] nums, int position) {
90+
if (position >= nums.length - 1) {
91+
return 0;
92+
}
93+
94+
int minJumps = Integer.MAX_VALUE;
95+
int farthestJump = Math.min(position + nums[position], nums.length - 1);
96+
97+
for (int nextPosition = position + 1; nextPosition <= farthestJump; nextPosition++) {
98+
int jumps = jumpHelper(nums, nextPosition);
99+
if (jumps != Integer.MAX_VALUE) {
100+
minJumps = Math.min(minJumps, jumps + 1);
101+
}
102+
}
103+
104+
return minJumps;
105+
}
106+
}
107+
108+
// Alternative approach using iterative
109+
class SolutionIterative {
110+
public int jump(int[] nums) {
111+
int jumps = 0;
112+
int currentEnd = 0;
113+
int farthest = 0;
114+
115+
for (int i = 0; i < nums.length - 1; i++) {
116+
farthest = Math.max(farthest, i + nums[i]);
117+
118+
if (i == currentEnd) {
119+
jumps++;
120+
currentEnd = farthest;
121+
122+
if (currentEnd >= nums.length - 1) {
123+
break;
124+
}
125+
}
126+
}
127+
128+
return jumps;
129+
}
130+
}
131+
132+
// Alternative approach using recursion with memoization
133+
class SolutionMemoization {
134+
public int jump(int[] nums) {
135+
int[] memo = new int[nums.length];
136+
Arrays.fill(memo, -1);
137+
return jumpHelper(nums, 0, memo);
138+
}
139+
140+
private int jumpHelper(int[] nums, int position, int[] memo) {
141+
if (position >= nums.length - 1) {
142+
return 0;
143+
}
144+
145+
if (memo[position] != -1) {
146+
return memo[position];
147+
}
148+
149+
int minJumps = Integer.MAX_VALUE;
150+
int farthestJump = Math.min(position + nums[position], nums.length - 1);
151+
152+
for (int nextPosition = position + 1; nextPosition <= farthestJump; nextPosition++) {
153+
int jumps = jumpHelper(nums, nextPosition, memo);
154+
if (jumps != Integer.MAX_VALUE) {
155+
minJumps = Math.min(minJumps, jumps + 1);
156+
}
157+
}
158+
159+
memo[position] = minJumps;
160+
return minJumps;
161+
}
162+
}
163+
164+
// More concise version
165+
class SolutionConcise {
166+
public int jump(int[] nums) {
167+
int jumps = 0, currentEnd = 0, farthest = 0;
168+
for (int i = 0; i < nums.length - 1; i++) {
169+
farthest = Math.max(farthest, i + nums[i]);
170+
if (i == currentEnd) {
171+
jumps++;
172+
currentEnd = farthest;
173+
}
174+
}
175+
return jumps;
176+
}
177+
}

0 commit comments

Comments
 (0)