LeetCode 每日一题笔记 日期:2026.05.25 题目:1871. 跳跃游戏 VII

LeetCode 每日一题笔记

0. 前言

  • 日期:2026.05.25
  • 题目:1871. 跳跃游戏 VII
  • 难度:中等
  • 标签:动态规划、前缀和、差分数组

1. 题目理解

问题描述 :

给定一个下标从 0 开始的二进制字符串 s 和两个整数 minJump 和 maxJump。

  • 从下标 0 出发
  • 在下标 i 处,可以跳跃到 [i + minJump, i + maxJump] 范围内
  • 只能落在值为 '0' 的下标上
    判断能否到达最后一个下标。

示例:

输入:s = "011010", minJump = 2, maxJump = 3

输出:true

2. 解题思路

核心观察

  • 每个位置 i 能否到达,取决于区间 [i-maxJump, i-minJump] 内是否有可达位置。
  • 用前缀和 快速查询区间内可达位置数量,用差分数组快速标记可达区间。

算法步骤

  1. 初始化可达标记与前缀和/差分数组。
  2. 遍历每个位置,判断是否能从前面的位置跳过来。
  3. 用前缀和快速查询区间和,用差分数组批量更新可达区间。
  4. 最后一位是否可达即为答案。

3. 代码实现

java 复制代码
package lc1871;

import java.util.Arrays;

public class Solution {
    public boolean canReach(String s, int minJump, int maxJump) {
        int n = s.length();
        boolean[] dp = new boolean[n];
        dp[0] = true;
        int[] pre = new int[n + 1];
        pre[1] = 1;

        for (int i = 1; i < n; i++) {

            int L = Math.max(0, i - maxJump);
            int R = i - minJump;

            if (R < 0) {
                dp[i] = false;
            } else {
                if (pre[R + 1] - pre[L] > 0 && s.charAt(i) == '0') {
                    dp[i] = true;
                } else {
                    dp[i] = false;
                }
            }
            pre[i + 1] = pre[i] + (dp[i] ? 1 : 0);
        }
        return dp[n - 1];
    }
}

4. 代码优化说明

java 复制代码
class Solution {
public boolean canReach(String s, int minJump, int maxJump) {
    // 转为字符数组,提高访问效率
    char ch[]=s.toCharArray();
    int n=ch.length;
    // 差分数组,用于区间更新可达标记
    int diff[]=new int[n];
    // 当前区间内可达位置的数量
    int sum=0;
    
    // 终点是1,直接不可能到达
    if(ch[n-1]=='1'){
        return false;
    }
    
    // 初始化差分数组:0位置可达,区间[0,0] +1
    diff[0]=1;
    diff[1]=-1;
    
    for(int i=0;i<n;i++){
        // 计算当前位置的可达状态(前缀和)
        sum+=diff[i];
        // 当前位置不可达,直接跳过
        if(sum<=0){
            continue;
        }
        // 当前位置是0,可以跳跃
        if(ch[i]=='0'){
            // 计算能跳到的左右边界
            int start=i+minJump;
            int end=Math.min(i+maxJump,n-1);
            
            // 区间无效,跳过
            if(start>end){
                continue;
            }
            // 直接跳到终点,返回true
            if(end==n-1){
                return true;
            }
            // 差分数组区间更新:[start,end] +1
            diff[start]+=1;
            diff[end+1]-=1;
        }
    }
    // 遍历结束未到达终点
    return false;
}
}

5. 复杂度分析

  • 时间复杂度 :O(n)O(n)O(n)
    一次遍历 + 差分数组 O(1)O(1)O(1) 区间更新。
  • 空间复杂度 :O(n)O(n)O(n)
    差分数组空间开销。

6. 总结

  • 核心:差分数组 + 前缀和 优化跳跃区间的可达性更新。
  • 优势:避免 O(n2)O(n^2)O(n2) 暴力遍历,效率大幅提升。
  • 本质:用区间标记代替逐个标记,是跳跃游戏的经典优化思路。
相关推荐
andyweike12 小时前
php笔记
开发语言·笔记·php
全速向光12 小时前
盖世游戏PC模拟器:手机也能畅玩电脑平台游戏
游戏·智能手机
Minecraft红客12 小时前
以撒的结合
python·游戏·电脑·娱乐
xian_wwq13 小时前
【学习笔记】等保合规安全基线核查实战
笔记·学习
M78佐菲14 小时前
ARM学习笔记(11)
linux·arm开发·笔记·嵌入式硬件·学习
M78佐菲14 小时前
ARM学习笔记(10)
linux·arm开发·笔记·嵌入式硬件·学习
李游Leo15 小时前
HarmonyOS 7 + ArkUI + RelationalStore 学习笔记:本地数据分层存储与状态持久化架构实践【鸿蒙心迹】
笔记·学习·架构·harmonyos
Cccp.12315 小时前
【leetcode】(七)前缀树和贪心算法
数据结构·leetcode·贪心算法
我命由我1234515 小时前
经纪人的职业定义
经验分享·笔记·学习·职场和发展·求职招聘·职场发展·学习方法
摇滚侠16 小时前
《On Java 中文版 基础卷》阅读笔记 对象无处不在 03
java·笔记·python