Talentd
FleetCode
Make and follow sheets.Sign in

Jump Game VII solution and explanation

MediumDynamic ProgrammingPrefix SumSliding WindowString6 min read35.4% acceptanceUpdated 9 Apr 2026
Jump Game VII - Leetcode 1871 - PythonNeetCode · 12:28 · 23K viewsWatch on YouTube
9 more videos on this problem
  1. Jump Game VII - Leetcode 1871 - PythonNeetCode · 12:28 · 23K views
  2. Jump Game VII | Brute Force | Optimal | Simple Intuition | Leetcode 1871 | codestorywithMIKcodestorywithMIK · 36:47 · 7K views
  3. Jump Game VII | Live Coding with Explanation | Leetcode - 1871Algorithms Made Easy · 15:27 · 4K views
  4. Jump Game VII | LeetCode 1871 | Coders CampCoders Camp · 10:03 · 3K views
  5. LeetCode 1871. Jump Game VIIHappy Coding · 15:06 · 942 views
  6. Leetcode 1871 | Jump Game VII | leetcode POTD | Dp | Sliding Window | DSACode With Vick · 22:50 · 701 views
  7. 1871. Jump Game VII (Leetcode Medium)Programming Live with Larry · 14:21 · 622 views
  8. Jump Game VII | LeetCode 1871 | Brute Force | Optimization | Dry Run + CodeStreak To Scale · 6:50 · 499 views
  9. Jump Game VII | Leetcode - 1871Shivam Gupta · 20:31 · 463 views
  10. 1871. Jump Game VII | Leetcode Daily - PythonLeetcode Daily · 7:33 · 362 views

The problem

You are given a 0-indexed binary string s and two integers minJump and maxJump. In the beginning, you are standing at index 0, which is equal to '0'. You can move from index i to index j if the following conditions are fulfilled:

  • i + minJump <= j <= min(i + maxJump, s.length - 1), and
  • s[j] == '0'.

Return true if you can reach index s.length - 1 in s, or false otherwise.

Example 1:

Input: s = "011010", minJump = 2, maxJump = 3
Output: true
Explanation:
In the first step, move from index 0 to index 3. 
In the second step, move from index 3 to index 5.

Example 2:

Input: s = "01101110", minJump = 2, maxJump = 3
Output: false

Constraints:

  • 2 <= s.length <= 105
  • s[i] is either '0' or '1'.
  • s[0] == '0'
  • 1 <= minJump <= maxJump < s.length

Approach overview

Problem Overview: You get a binary string s where 0 means you can land on that index and 1 blocks it. Starting at index 0, you can jump to any index j such that minJump ≤ j - i ≤ maxJump. The goal is to determine whether the last index is reachable.

Approach 1: Breadth-First Search (BFS) (Time: O(n), Space: O(n))

Treat each index as a node in a graph and each valid jump as an edge. Use a queue to run BFS starting from index 0. For each popped index i, iterate through the range [i + minJump, i + maxJump] and push positions where s[j] == '0'. To avoid scanning the same region repeatedly, track the farthest index already explored and only process new indices beyond that boundary. A visited array prevents revisiting nodes. This approach works well because BFS guarantees that every reachable index is processed exactly once.

The idea fits naturally with graph traversal and highlights reachability. The string is essentially a linear graph where edges represent valid jump distances. BFS makes the logic straightforward, though you still need the optimization that avoids repeatedly scanning the same jump window.

Approach 2: Sliding Window Optimization (Time: O(n), Space: O(n))

The optimized approach uses dynamic programming with a sliding window. Define dp[i] as whether index i is reachable. For each position i, check if there exists a reachable index within the window [i - maxJump, i - minJump]. Instead of scanning the entire range each time, maintain a running count of reachable positions inside that window.

As you iterate through the string, expand the window by adding dp[i - minJump] and shrink it by removing dp[i - maxJump - 1]. If the window count is greater than zero and s[i] == '0', mark dp[i] = true. This guarantees each index is processed once, giving linear time complexity.

This sliding window trick avoids repeated range checks and effectively simulates a prefix-sum style reachability check. It turns a potentially quadratic search into a strict O(n) scan.

Recommended for interviews: Interviewers typically expect the sliding window dynamic programming solution. Starting with the BFS interpretation shows you understand the reachability model. Moving to the optimized sliding window approach demonstrates algorithmic maturity by reducing repeated work and achieving true O(n) performance.

Approach 1: Breadth-First Search (BFS) Approach

A BFS approach involves using a queue to explore all possible indices starting from index 0. Each index is checked for the conditions, and if any index meets the criteria, it is added to the queue for further exploration. This ensures all reachable indices are visited.

def canReach(s: str, minJump: int, maxJump: int) -> bool:
    n = len(s)
    reachable = [False] * n
    reachable[0] = True
    farthest = 0
    for i in range(n):
        if reachable[i]:
            for j in range(max(i + minJump, farthest + 1), min(i + maxJump + 1, n)):
                if s[j] == '0':
                    reachable[j] = True
            farthest = i + maxJump
    return reachable[-1]
class Solution {
    public boolean canReach(String s, int minJump, int maxJump) {
        int n = s.length();
        boolean[] reachable = new boolean[n];
        reachable[0] = true;
        int farthest = 0;
        for (int i = 0; i < n; i++) {
            if (reachable[i]) {
                for (int j = Math.max(i + minJump, farthest + 1); j <= Math.min(i + maxJump, n - 1); j++) {
                    if (s.charAt(j) == '0') reachable[j] = true;
                }
                farthest = i + maxJump;
            }
        }
        return reachable[n - 1];
    }
}
#include <vector>
#include <string>
using namespace std;

class Solution {
public:
    bool canReach(string s, int minJump, int maxJump) {
        int n = s.size();
        vector<bool> reachable(n, false);
        reachable[0] = true;
        int farthest = 0;
        for (int i = 0; i < n; i++) {
            if (reachable[i]) {
                for (int j = max(i + minJump, farthest + 1); j <= i + maxJump && j < n; j++) {
                    if (s[j] == '0') reachable[j] = true;
                }
                farthest = i + maxJump;
            }
        }
        return reachable[n - 1];
    }
};
var canReach = function(s, minJump, maxJump) {
    const n = s.length;
    const reachable = Array(n).fill(false);
    reachable[0] = true;
    let farthest = 0;
    for (let i = 0; i < n; i++) {
        if (reachable[i]) {
            for (let j = Math.max(i + minJump, farthest + 1); j <= Math.min(i + maxJump, n - 1); j++) {
                if (s[j] === '0') reachable[j] = true;
            }
            farthest = i + maxJump;
        }
    }
    return reachable[n - 1];
};
#include <stdbool.h>
#include <string.h>

bool canReach(char * s, int minJump, int maxJump) {
    int n = strlen(s);
    bool *reachable = (bool*)calloc(n, sizeof(bool));
    reachable[0] = true;
    int farthest = 0;
    for (int i = 0; i < n; i++) {
        if (reachable[i]) {
            for (int j = max(i + minJump, farthest + 1); j <= i + maxJump && j < n; j++) {
                if (s[j] == '0') reachable[j] = true;
            }
            farthest = i + maxJump;
        }
    }
    bool result = reachable[n - 1];
    free(reachable);
    return result;
}
public class Solution {
    public bool CanReach(string s, int minJump, int maxJump) {
        int n = s.Length;
        bool[] reachable = new bool[n];
        reachable[0] = true;
        int farthest = 0;
        for (int i = 0; i < n; i++) {
            if (reachable[i]) {
                for (int j = Math.Max(i + minJump, farthest + 1); j <= Math.Min(i + maxJump, n - 1); j++) {
                    if (s[j] == '0') reachable[j] = true;
                }
                farthest = i + maxJump;
            }
        }
        return reachable[n - 1];
    }
}

This Python solution makes use of a list to track if each position in the string is reachable. By iterating through the string, it checks each index, marks reachable indices, and determines if the final index can be reached following the same logic as previous implementations.

Complexity

Time Complexity: O(n)
Space Complexity: O(n)

Try this approach in the editor

Approach 2: Sliding Window Optimization

To further optimize, a sliding window or prefix sum method is used to reduce the number of operations needed by focusing on maintaining a window of reachable indices, eliminating inner loops for checking reachable segments, and accumulating results incrementally.

def canReach(s: str, minJump: int, maxJump: int) -> bool:
    n = len(s)
    dp = [False] * n
    dp[0] = True
    reached = 0
    for i in range(1, n):
        if i >= minJump and dp[i - minJump]:
            reached += 1
        if i > maxJump and dp[i - maxJump - 1]:
            reached -= 1
        dp[i] = (s[i] == '0' and reached > 0)
    return dp[-1]
class Solution {
    public boolean canReach(String s, int minJump, int maxJump) {
        int n = s.length();
        boolean[] dp = new boolean[n];
        dp[0] = true;
        int reached = 0;
        for (int i = 1; i < n; i++) {
            if (i >= minJump && dp[i - minJump]) {
                reached++;
            }
            if (i > maxJump && dp[i - maxJump - 1]) {
                reached--;
            }
            dp[i] = (s.charAt(i) == '0' && reached > 0);
        }
        return dp[n - 1];
    }
}
#include <vector>
#include <string>
using namespace std;

class Solution {
public:
    bool canReach(string s, int minJump, int maxJump) {
        int n = s.size();
        vector<bool> dp(n, false);
        dp[0] = true;
        int reached = 0;
        for (int i = 1; i < n; i++) {
            if (i >= minJump && dp[i - minJump]) {
                ++reached;
            }
            if (i > maxJump && dp[i - maxJump - 1]) {
                --reached;
            }
            dp[i] = (s[i] == '0' && reached > 0);
        }
        return dp[n - 1];
    }
};
var canReach = function(s, minJump, maxJump) {
    const n = s.length;
    const dp = Array(n).fill(false);
    dp[0] = true;
    let reached = 0;
    for (let i = 1; i < n; i++) {
        if (i >= minJump && dp[i - minJump]) {
            reached++;
        }
        if (i > maxJump && dp[i - maxJump - 1]) {
            reached--;
        }
        dp[i] = (s[i] === '0' && reached > 0);
    }
    return dp[n - 1];
};
#include <stdbool.h>
#include <string.h>

bool canReach(char * s, int minJump, int maxJump) {
    int n = strlen(s);
    bool *dp = (bool*)calloc(n, sizeof(bool));
    dp[0] = true;
    int reached = 0;
    for (int i = 1; i < n; i++) {
        if (i >= minJump && dp[i - minJump]) {
            reached++;
        }
        if (i > maxJump && dp[i - maxJump - 1]) {
            reached--;
        }
        dp[i] = (s[i] == '0' && reached > 0);
    }
    bool result = dp[n - 1];
    free(dp);
    return result;
}
public class Solution {
    public bool CanReach(string s, int minJump, int maxJump) {
        int n = s.Length;
        bool[] dp = new bool[n];
        dp[0] = true;
        int reached = 0;
        for (int i = 1; i < n; i++) {
            if (i >= minJump && dp[i - minJump]) {
                reached++;
            }
            if (i > maxJump && dp[i - maxJump - 1]) {
                reached--;
            }
            dp[i] = (s[i] == '0' && reached > 0);
        }
        return dp[n - 1];
    }
}

Similar to the other solutions, the Python implementation efficiently tracks reachability using a fixed-length window. By focusing on counting reachable indices within the jump window, it skips recalculating the same positions.

Complexity

Time Complexity: O(n)
Space Complexity: O(n)

Try this approach in the editor

Approach 3: Prefix Sum + Dynamic Programming

We define a prefix sum array pre of length n+1, where pre[i] represents the number of reachable positions in the first i positions of s. We define a boolean array f of length n, where f[i] indicates whether s[i] is reachable. Initially, pre[1] = 1 and f[0] = true.

Consider i \in [1, n), if s[i] = 0, then we need to determine whether there exists a position j in the first i positions of s, such that j is reachable and the distance from j to i is within [minJump, maxJump]. If such a position j exists, then we have f[i] = true, otherwise f[i] = false. When determining whether j exists, we can use the prefix sum array pre to determine whether such a position j exists in O(1) time.

The final answer is f[n-1].

The time complexity is O(n), and the space complexity is O(n). Here, n is the length of the string s.

function canReach(s: string, minJump: number, maxJump: number): boolean {
    const n = s.length;
    const pre: number[] = Array(n + 1).fill(0);
    pre[1] = 1;
    const f: boolean[] = Array(n).fill(false);
    f[0] = true;
    for (let i = 1; i < n; ++i) {
        if (s[i] === '0') {
            const [l, r] = [Math.max(0, i - maxJump), i - minJump];
            f[i] = l <= r && pre[r + 1] - pre[l] > 0;
        }
        pre[i + 1] = pre[i] + (f[i] ? 1 : 0);
    }
    return f[n - 1];
}
func canReach(s string, minJump int, maxJump int) bool {
	n := len(s)
	pre := make([]int, n+1)
	pre[1] = 1
	f := make([]bool, n)
	f[0] = true
	for i := 1; i < n; i++ {
		if s[i] == '0' {
			l, r := max(0, i-maxJump), i-minJump
			f[i] = l <= r && pre[r+1]-pre[l] > 0
		}
		pre[i+1] = pre[i]
		if f[i] {
			pre[i+1]++
		}
	}
	return f[n-1]
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Breadth-First Search (BFS) Approach

Time Complexity: O(n)
Space Complexity: O(n)

Sliding Window Optimization

Time Complexity: O(n)
Space Complexity: O(n)

Prefix Sum + Dynamic Programming–

Complexity analysis

ApproachTimeSpaceWhen to Use
Breadth-First Search (BFS)O(n)O(n)When modeling the problem as graph reachability or when explaining the intuition step-by-step
Sliding Window Dynamic ProgrammingO(n)O(n)Preferred optimal solution for interviews; avoids repeated range scans using a running window

Frequently asked questions

Is Jump Game VII easy or hard?

Jump Game VII is rated Medium but often feels closer to hard for many candidates. The challenge is recognizing that naive range checks are too slow and applying a sliding window optimization to reduce the complexity to O(n).

How to solve Jump Game VII in O(n)?

Use a DP array where dp[i] indicates if index i is reachable. Maintain a sliding window count of reachable indices between i - maxJump and i - minJump. If the count is positive and s[i] equals '0', mark dp[i] as reachable. Updating the window incrementally keeps the entire algorithm linear.

What is the best approach for Jump Game VII?

The most efficient approach uses sliding window dynamic programming. Track whether each index is reachable and maintain a running count of reachable indices within the window [i - maxJump, i - minJump]. This avoids scanning the entire range for every position and achieves O(n) time complexity.

Is Jump Game VII asked at Google/Amazon/Meta?

Jump Game style problems frequently appear in interviews at companies like Amazon, Google, and Meta. Variants test reachability, dynamic programming, and sliding window optimization. Interviewers often expect candidates to move from a BFS idea to an O(n) optimized solution.

What data structure is used in Jump Game VII?

Common implementations use a queue for the BFS approach and an array for dynamic programming. The optimized solution also uses a sliding window counter, similar to prefix sum techniques, to track reachable positions efficiently.

What is the time complexity of Jump Game VII?

The optimal solution runs in O(n) time where n is the length of the string. Each index is processed once while maintaining a sliding window of reachable positions. Space complexity is O(n) for the DP or visited array.

Jump Game VII Python or Java solution approach?

Both Python and Java implementations typically follow the sliding window DP method. Maintain a dp array and update a running window count as you iterate through the string. This keeps the complexity O(n) and works efficiently even for large input sizes.

Comments

Now write it yourselfClose this page and solve Jump Game VII in the editor, without looking.
Practise Jump Game VII