1871. 跳跃游戏 VII
题目地址(1871. 跳跃游戏 VII)
https://leetcode-cn.com/problems/jump-game-vii/
题目描述
前置知识
BFS
动态规划
前缀和
公司
暂无
BFS(超时)
思路
我们可以对问题进行抽象。将 0 抽象为图中的点,将每一个 0 与其能够到达的比它索引大的 0抽象为边。那么问题转化为从索引为 0 的点与索引为 n - 1 的点是否联通。我们有很多方法能够解决这个问题,不妨使用 BFS。
关键点
将题目抽象为图的联通问题
代码
语言支持:Python3
Python3 Code:
复杂度分析
令 n 为数组长度。
时间复杂度:$O(n^2)$
空间复杂度:$O(n)$
动态规划
思路
定义 dp(i) 为从索引为 0 的点是否能够到达索引为 i 的点。显然 dp(i) 只有在满足以下两个条件才为 true:
s[i] == '0'
s[j] == '0' 其中 max(0, i - maxJump) <= j <= max(0, i - minJump)
于是,我们可以枚举所有满足条件的 j ,并观察其是否满足上述条件即可。
代码:
由于枚举 i 和 j 的复杂度为都为 $O(n)$,因此总的时间复杂度为 $O(n^2)$,代入题目会超时。
我们需要对其进行优化。我们发现算法条件在于寻找满足条件的 j,而满足条件的 j 实际上就是区间[max(0,i-maxJump), max(0, i-minJump)] 中可以从 0 点到达的点。
换句话说就是 dp 数组的区间 [max(0,i-maxJump), max(0, i-minJump)] 中是否存在一个 true。
那么这该如何求呢?我举个例子你就懂了。
比如一个数组 [false, true, false, false, true],我想知道区间 [2,3] 是否有 true。
朴素的做法是遍历:
如果我想知道任意合法区间 [s,e] 是否有 true。
则可以:
实际上,我们有可以将 bools 映射到整数,其中 false 映射为 0,true 映射为 1,并对 bools 求前缀和。这样就可以通过前缀和在 $O(1)$ 时间获取到任意区间的 true 的个数。
代码:
关键点
对 DP 数组本身求前缀和,而不是原数组
代码
语言支持:Python3
Python3 Code:
复杂度分析
令 n 为数组长度。
时间复杂度:$O(n)$
空间复杂度:$O(n)$
平衡二叉树
思路
我们可以将所有的 0 的索引按照升序顺序存起来,不妨令这个存储 0 索引的数据结构名为 zeros。
然后继续使用前面提到的动态规划思路,即 dp(i) 表示是否可从索引为 0 的点到达索引为 1 的点。唯一不同的是,这里不使用前缀和加速。
对于每一个可以到达的点(初始为索引为 0 的点),我们都执行一下判断:
当前点 i 可以到跳的点为 j。其中 j 属于区间[i + minJump, i + maxJump]。判断 j 是否存在于 zeros。 (操作 1)
如果存在 zero[k] == j 。则令 dp[j] = true(操作 2)
最后返回最后 dp[n] 即可。
这种做法时间复杂度取决于 zeros 的数据结构。由于 zero 需要支持区间查找(操作 1),并且 zeros 是升序的,因此使用数组来存储就没问题。区间查找使用二分即可。
不过由于 zeros 最差的情况下可以到达 n 的数据规模,而此时操作 2 复杂度可以到达 $O(n)$,因此对于全为 0 的情况,时间复杂度为 $O(n^2)$。
我们可以使用平衡二叉树,并在每次操作 2 结束后将 v 从 zeros 移除来进行加速(平衡二叉树删除只需要 logn 时间)
并且由于 zeros 中的值都最多只会被访问一次,因此时间复杂度为 $O(n)$。但是我们使用二分查找时间复杂度是 $logn$,因此总的时间不大于 $nlogn$。之所以说不大于,是因为 zeros 在不断变小,因此每次二分时间也在不断缩减。
关键点
使用平衡二叉树不断执行删除以降低复杂度
代码
语言支持:Python3
Python3 Code:
复杂度分析
令 n 为数组长度。
时间复杂度:$O(nlogn)$
空间复杂度:$O(n)$
此题解由 力扣刷题插件 自动生成。
力扣的小伙伴可以关注我,这样就会第一时间收到我的动态啦~
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
最后更新于