为了选出新的首领,青蛙部落准备在河边举办一场比赛,部落的首领必须同时具备强健的体魄和灵活的头脑,所以举办方制定了如下的比赛规则:
- 假定河流被等分为若干个单元格,在其中的一些单元格内放有一块石子。
- 石子的位置存在stones中(用石子所在单元格的序号升序表示)。
- 候选人只能从一块石子跳到另一块石子,跳入水中即视为淘汰。
- 开始时,候选人站在第一块石子上,规定第一步只能跳一个单元格的距离,即只能从单元格1跳到单元格2,即
stones[0]
为0
,stones[1]
必须为1
。- 为了选出最优秀的候选人,规定如果候选人上一步跳跃了
k
个单位,那么它接下来的跳跃距离只能为k-1
、k
或k+1
个单位,而且只准向前跳(终点的方向)。- 胜利的条件就是跳到最后一块石子上(跳不到或者跳过头都视为淘汰)。
举办方为了比赛的公平和多样性,设计了很多不同的赛道stones
,每个候选人都会从这些赛道中抽取自己的赛道,所以必须保证每条赛道都是有解的(即肯定有一种满足比赛规则的跳法能胜利),所以举办方请你来帮助验证赛道的有效性。
示例 1:
输入:stones = [0,1,3,5,6,8,12,17]
输出:true
解释:该赛道是有效的,按照如下方案跳跃:跳1
个单位到第2
块石子, 然后跳2
个单位到第3
块石子, 接着跳2
个单位到第4
块石子, 然后跳3
个单位到第6
块石子, 跳4
个单位到第7
块石子, 最后,跳5
个单位到第8
个石子(即最后一块石子)。
示例 2:
输入:stones = [0,1,2,3,4,8,9,11]
输出:false
解释:这是因为第5
和第6
个石子之间的间距太大,没有可选的方案供青蛙跳跃过去。
提示:
2 <= stones.length <= 2000
0 <= stones[i] <= 231 - 1
stones[0] == 0
标签:回溯,记忆化搜索,动态规划
1.记忆化搜索(DFS)
数据结构:set,map/dict
知识点:
Python:
- 用functools
里的@lru_cache(None)
及其语法糖@cache
来实现记忆化搜索
- set
和dict
的查找复杂度(a in set(b))
都为 O ( 1 ) \mathcal{O}(1) O(1),而list
查找复杂度为 O ( n )