Lesson 218 of 250
1871. Jump Game VII
NeetCode: Jump Game VII · LeetCode: 1871. Jump Game VII · Difficulty: Medium
Given a binary string s (0-indexed) and two integers minJump and maxJump, start at index 0 (guaranteed to be '0'). From index i you can jump to j if i + minJump <= j <= min(i + maxJump, n - 1) and s[j] == '0'. Return true if you can reach index n - 1.
Example
Input: s = "011010", minJump = 2, maxJump = 3 Output: true (0 -> 3 -> 5)
Input: s = "01101110", minJump = 2, maxJump = 3 Output: falseBrute force: look back at every possible source
Let reach[i] mean index i can be reached. Index i is reachable if s[i] == '0' and some index j in [i - maxJump, i - minJump] is reachable. Scanning that window for every i costs up to maxJump per index.
class Solution {
public boolean canReach(String s, int minJump, int maxJump) {
int n = s.length();
boolean[] reach = new boolean[n];
reach[0] = true;
for (int i = 1; i < n; i++) {
if (s.charAt(i) != '0' || i < minJump) {
continue;
}
int lo = Math.max(0, i - maxJump);
int hi = i - minJump;
for (int j = lo; j <= hi; j++) {
if (reach[j]) {
reach[i] = true;
break;
}
}
}
return reach[n - 1];
}
}
public class Main {
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.canReach("011010", 2, 3));
System.out.println(s.canReach("01101110", 2, 3));
System.out.println(s.canReach("0", 1, 1));
System.out.println(s.canReach("00", 1, 1));
System.out.println(s.canReach("01", 1, 1));
}
}true
false
true
true
falseTime: O(n * maxJump). Space: O(n).
Optimal: sliding window of reachable sources
Only whether the window [i - maxJump, i - minJump] contains any reachable index matters, that is, whether a count is positive. The window slides right by one each step, so the count can be maintained incrementally: moving to i, index i - minJump enters the window (add it if reachable) and index i - maxJump - 1 leaves it (subtract it if reachable). Each index enters and leaves once, so the scan is linear.
class Solution {
public boolean canReach(String s, int minJump, int maxJump) {
int n = s.length();
boolean[] reach = new boolean[n];
reach[0] = true;
int window = 0; // reachable indices in [i - maxJump, i - minJump]
for (int i = 1; i < n; i++) {
if (i >= minJump && reach[i - minJump]) {
window++;
}
if (i > maxJump && reach[i - maxJump - 1]) {
window--;
}
reach[i] = s.charAt(i) == '0' && window > 0;
}
return reach[n - 1];
}
}
public class Main {
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.canReach("011010", 2, 3));
System.out.println(s.canReach("01101110", 2, 3));
System.out.println(s.canReach("0", 1, 1));
System.out.println(s.canReach("00", 1, 1));
System.out.println(s.canReach("01", 1, 1));
}
}true
false
true
true
falseTime: O(n). Space: O(n) for the reach array.
