跳跃游戏VII(dp)
1.题目描述
给你一个下标从 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 。
原题链接:https://leetcode-cn.com/problems/jump-game-vii
2.简析
这道题的数据范围是 因此这里考虑采用
复杂度的算法,首先考虑dp;首先定义一个数组
,
表示是否能移动到当前下标
。而能否移动到下标
取决于之前的状态,当
否则其状态转移方程如下:
但是针对每个下标点 ,都需要遍历前面
的元素,算法复杂度仍为
。由于这里是求这个范围内是否存在1,因此可以采用前缀和进行优化,在dp过程中同时记录前缀和,然后状态转移的时候可以利用前缀和在
的时间复杂度内判断当坐标点是否可以由目标区间内某点转移而来,最终整个算法的复杂度为
。
3.代码示例
bool canReach(string s, int minJump, int maxJump) {
int n = s.size();
if(s[n-1] == '1') return false;
int presum[n+1], f[n];
memset(presum, 0, sizeof presum);
memset(f, 0, sizeof f);
f[0] = presum[1] = 1;
for(int i=1; i<n; ++i){
if(s[i] == '0' && i >= minJump){
f[i] = presum[i+1-minJump] - presum[max(0, i-maxJump)] > 0? 1 : 0;
}
presum[i+1] = presum[i] + f[i];
}
return f[n-1]>0;
}