Solution: Jump Game I
Let's solve the Jump Game I challenge using the Greedy pattern.
Statement#
In a single-player jump game, the player starts at one end of a series of squares, with the goal of reaching the last square.
At each turn, the player can take up to steps towards the last square, where is the value of the current square.
For example, if the value of the current square is , the player can take either steps, or steps, or step in the direction of the last square. The player cannot move in the opposite direction, that is, away from the last square.
You have been tasked with writing a function to validate whether a player can win a given game or not.
You’ve been provided with the nums integer array, representing the series of squares. The player starts at the first index and, following the rules of the game, tries to reach the last index.
If the player can reach the last index, your function returns TRUE; otherwise, it returns FALSE.
Constraints:
-
nums.length -
nums[i]
Solution#
You may have already brainstormed some approaches and have an idea of how to solve this problem. Let’s explore some of these approaches and figure out which one to follow based on considerations such as time complexity and implementation constraints.
Naive approach#
The naive approach is to attempt all possible jump patterns to traverse from the initial position to the final position. The process begins at the starting position and involves jumping to every reachable index. This process is repeated until the last index is reached. In case we are unable to proceed further, a backtrack is performed to explore alternative paths. This method, although inefficient, ensures that all potential paths are explored to reach the final position. However, the time complexity of the backtracking approach will be exponential.
Optimized approach using the greedy pattern#
Alternatively, an optimized approach to solve this problem is using the greedy technique by traversing our array backward. We check the elements one by one from the last element of our array. We keep track of the elements that can reach the ending point directly and verify if there are any possible paths to these indexes. We’re “greedy” because we always pick the nearest preceding element that provides a path to the ending point. We can afford to be “greedy”, since there is no danger of overshooting the target. The value at each index specifies the longest jump we can make and doesn’t restrict us from making a smaller jump if that suits us better.
1 of 11
2 of 11
3 of 11
4 of 11
5 of 11
6 of 11
7 of 11
8 of 11
9 of 11
10 of 11
11 of 11
Note: In the following section, we will gradually build the solution. Alternatively, you can skip straight to just the code.
Step-by-step solution construction#
Setting the last element of the array as our target is the cornerstone of our strategy. In simple terms, this target is the number we’re trying to reach from the start of our array. The first step is to actually set the target. While doing this, we can also learn how to change the target, if needed.
We’ve learned how to move backward and change our target along the way. Now, let’s take our solution one step further. We can use the value at each index to see how many indexes we can jump forward from it.
Next, we can check whether the current target is reachable from the preceding index.
If it is, that preceding index becomes the new target. If it isn't, we check the index before that, and so on, until we reach the start of the array.
If, at any point, we get all the way to the start of the array without finding a preceding index from which the current target is reachable, then there is no way to win the game. On the other hand, if each index is reachable from some preceding index, there is at least one way to win the game.
Just the code#
Here's the complete solution to this problem:
Solution summary#
- Set the last index of the array as the target index.
- Traverse the array backward and verify if we can reach the target index from any of the previous indexes.
-
If we can reach it, we update the target index with the index that allows us to jump to the target index.
-
We repeat this process until we’ve traversed the entire array.
-
- Return TRUE if, through this process, we can reach the first index of the array. Otherwise, return FALSE.
Time complexity#
The time complexity of the above solution is , since we traverse the array only once, where is the number of elements in the array.
Space complexity#
The space complexity of the above solution is , because we do not use any extra space.
Jump Game I
Boats to Save People