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

LeetCode 每日一题笔记

0. 前言

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

1. 题目理解

问题描述

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

  • 从下标 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) 暴力遍历,效率大幅提升。
  • 本质:用区间标记代替逐个标记,是跳跃游戏的经典优化思路。
相关推荐
IT19954 小时前
Dify笔记-一种知识库文件上传失败报错500解决方法
笔记
IronMurphy5 小时前
AI Agent 学习笔记 Day 1:大模型基础、API 调用与 Prompt 工程
人工智能·笔记·学习
csdn_aspnet5 小时前
C++ 算法 LeetCode 编号 70 - 爬楼梯
开发语言·c++·算法·leetcode
圣保罗的大教堂5 小时前
leetcode 2770. 达到末尾下标所需的最大跳跃次数 中等
leetcode
爱学习的章鱼哥5 小时前
AI编程学习笔记(I)
人工智能·笔记·学习·ai编程
·醉挽清风·5 小时前
学习笔记—MySQL—索引
笔记·学习·mysql
tkokof15 小时前
捉虫(Bug)再记
游戏·bug·游戏开发
数智工坊5 小时前
《我看见的世界:李飞飞自传》第7-12章阅读笔记:从ImageNet到以人为本的AI
人工智能·笔记
数智工坊5 小时前
钱钟书《围城》第1-5章阅读笔记:一场关于人生困境的提前预演
笔记·生活
sbjdhjd5 小时前
03(中)| K8s控制器:DaemonSet+Job+CronJob 逐行解析与生产落地
运维·笔记·docker·云原生·容器·kubernetes·开源