LeetCode第242场周赛第三题——5765. 跳跃游戏 VII(dp+前缀和)
题目描述
给你一个下标从 0 开始的二进制字符串 s 和两个整数 minJump 和 maxJump 。一开始,你在下标 0 处,且该位置的值一定为 '0' 。当同时满足如下条件时,你可以从下标 i 移动到下标 j 处:
- i + minJump <= j <= min(i + maxJump, s.length - 1)
- s[j] == '0'.
如果你可以到达 s 的下标 s.length - 1 处,请你返回 true ,否则返回 false 。
示例 1:
输入:s = "011010", minJump = 2, maxJump = 3
输出:true
解释:
第一步,从下标 0 移动到下标 3 。
第二步,从下标 3 移动到下标 5 。
示例 2:
输入:s = "01101110", minJump = 2, maxJump = 3
输出:false
提示:
2 <= s.length <= 105
s[i] 要么是 '0' ,要么是 '1'
s[0] == '0'
1 <= minJump <= maxJump < s.length
解题思路
这题一开始没有想到前缀和,所以就超时了。后面看了y总的分析,就想明白了。我们可以用dp的思路,用f[i] 来表示当前位置是否可以到达(0不可以,1可以),这样一来我们分析倒数第二步的区间应该是落在[i - maxJump, i - minJump],很明显此时我们只需要确定从开始位置是否能到达区间[i - maxJump, i - minJump]的某一个位置即可。
如果我们想要知道[i, j]区间有多少个位置能到达,我们可以用一个prefix数组来记录前缀和,那么就可以得出其实是有f[j] - f[i - 1]个位置可以跳到,只要 f[j] - f[i - 1] > 0 ,就表示可以跳到第i个位置,此时将 f[i] 设置为1
注意:
- 更新前缀和是用 f 数组
- 且要满足 i - minJump >= 1,即保证区间一定存在
AC代码
1 class Solution { 2 public boolean canReach(String s, int minJump, int maxJump) { 3 char[] c = s.toCharArray(); 4 int n = c.length; 5 int[] prefix = new int[n + 1]; 6 // f[i] = 0 表示不能到达当前位置,f[i] = 1表示可以到达当前位置 7 int[] f = new int[n + 1]; 8 f[1] = 1; 9 // 表示前i个位置有几个位置是可以跳到的 10 prefix[1] = 1; 11 for (int i = 2; i <= n; i ++) { 12 // 这里需要判断一下右端点是否存在,即区间是否存在 13 if (c[i - 1] == '0' && i - minJump >= 1) { 14 int left = Math.max(1, i - maxJump); 15 int right = i - minJump; 16 if (prefix[right] > prefix[left - 1]) { 17 f[i] = 1; 18 } 19 } 20 prefix[i] = prefix[i - 1] + f[i]; 21 } 22 return f[n] > 0; 23 } 24 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能