题目:给你一个整数数组 arr ,你一开始在数组的第一个元素处(下标为 0)。每一步,你可以从下标 i 跳到下标:
    i + 1 满足:i + 1 < arr.length
    i - 1 满足:i - 1 >= 0
    j 满足:arr[i] == arr[j] 且 i != j
请你返回到达数组最后一个元素的下标处所需的 最少操作次数 。注意:任何时候你都不能跳到数组外面。

来源:https://leetcode-cn.com/problems/jump-game-iv/

法一: 自己的超时代码    dfs

思路:利用回溯的方法,把每次要遍历的记入k中,同时记录每个分支遍历过的索引,防止重复遍历,剪枝条件是:如果某次回溯的时候,某个到达个位置的次数大于之前记录的值了,直接结束回溯。这个题无法用dp,解题的时候要快速识别出无法用dp动态规划来解决。或即使用dp也很复杂。

from typing import List
from collections import defaultdict
from functools import lru_cache
class Solution:
def minJumps(self, arr: List[int]) -> int:
# print('3333333333', len(arr))
d = defaultdict(list)
size = len(arr)
for i,j in enumerate(arr):
d[j] = d[j] + [i]
# @lru_cache(None)
memo = defaultdict(lambda : size)
def recursion(index, cou=0, used=[-1,0]):
# 回溯结束条件
if index == size-1:
# print('*' * 8, cou)
return cou
# 加上这个剪枝条件后,仍然超时
# 这个条件是如果现在的cou大于之前记录的值,则直接返回,结束这次回溯
if memo[index] < cou:
print('-'* 30)
return size
# if index == 0:
# k = [1] + d[arr[0]][1:]
# # print('kkkkkkkkkkkkkkkkk')
# else: # used [-1,0]的初始值中的-1是为了处理index=0时的情况
# 这儿之所以取set是因为有重复值的情况,
k = list(set(([index-1] if index-1 not in used else []) \
+ ([index+1] if index+1 not in used else []) \
+ list(set(d[arr[index]]) - set(used))))
# 当k为空的时候说明,两边都走过了,也无法跳跃了,直接返回
if k == []:
return cou
memo[index] = cou
res = size
cou += 1
for j in k:
# 这里是关键,每次回溯的时候,传递下一次要跳到的地方,跳过的步数,以及已经跳过的位置,
# 如果没有这个used,程序会陷入死循环,实际上是为了防止重复遍历
res = min(res, recursion(j, cou=cou, used=used+[j]))
return res
return recursion(index=0)
if __name__ == '__main__':
duixiang = Solution()
# a = duixiang.minJumps(arr = [100,-23,-23,404,100,23,23,23,3,404])
a = duixiang.minJumps(arr = [68,-94,-44,-18,-1,18,-87,29,-6,-87,-27,37,-57,7,
18,68,-59,29,7,53,-27,-59,18,-1,18,-18,-59,-1,-18,
-84,-20,7,7,-87,-18,-84,-20,-27])
print(a)

法二:bfs   别人的代码

思路:这个题是一个非常典型的最短路径问题,天然具有应用bfs的优势,因为在这个最短路径问题中,每走一步都是在向目标靠近,而对于每个位置而言,从出发点第一次到达该位置的步数即到达该点的最小值,所以无需再次遍历,由此便想到用bfs,将要走的位置放在队列的前面,由此便控制住了步数,最先到达末尾的即最短的步数。

from collections import defaultdict
from typing import List
class Solution:
def minJumps(self, arr: List[int]) -> int:
d = defaultdict(list)
n = len(arr)
for i in range(n):
d[arr[i]].append(i)
vis = [0] * n
vis[0] = 1
q = [(0, 0)]
while q:
# i是当前位置的索引,k是走过的步数,
i, k = q.pop(0)
# 遍历当前位置的上一个和下一个,以及可以跳跃的位置
for j in d[arr[i]] + [i - 1, i + 1]:
# 如果出界或者已经遍历过了,直接进行下一个循环
if j < 0 or j >= n or vis[j]:
continue
# 一旦跳到最后一个位置了,则它即为最少的步数,直接返回结果
if j == n - 1:
return k + 1
# 遍历过的标记为1
vis[j] = 1
# 把当前的位置放入队列,并且把步数加1
q.append((j, k + 1))
# 某个值的索引一旦遍历过其中一个后,就置为[],因为其余的索引已经放入队列了,无需再次遍历
# 如果第二次在相同的值之间跳跃,则浪费了步数,肯定不是最短的
d[arr[i]] = []
return 0

ttt

5314跳跃游戏IV的更多相关文章

  1. lintcode: 跳跃游戏 II

    跳跃游戏 II 给出一个非负整数数组,你最初定位在数组的第一个位置. 数组中的每个元素代表你在那个位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 样例 给出数组A =  ...

  2. lintcode : 跳跃游戏

    跳跃游戏 给出一个非负整数数组,你最初定位在数组的第一个位置. 数组中的每个元素代表你在那个位置可以跳跃的最大长度. 判断你是否能到达数组的最后一个位置. 样例 A = [2,3,1,1,4],返回 ...

  3. 【LeetCode每天一题】Jump Game II(跳跃游戏II)

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  4. LeetCode(45): 跳跃游戏 II

    Hard! 题目描述: 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 示例: 输入: [ ...

  5. 计蒜客-跳跃游戏二 (简单dp)

    题目链接:https://nanti.jisuanke.com/t/20                                         跳跃游戏二 给定一个非负整数数组,假定你的初始 ...

  6. [Leetcode]44.跳跃游戏Ⅰ&&45.跳跃游戏Ⅱ

    跳跃游戏链接 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] 输出 ...

  7. 跳跃游戏 12 · Jump Game 12

    跳跃游戏 1 [抄题]: [思维问题]: [一句话思路]: [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入): [画图]: [一刷]: 由于要用itera ...

  8. LeetCode:跳跃游戏【55】

    LeetCode:跳跃游戏[55] 题目描述 给定一个非负整数数组,你最初位于数组的第一个位置.数组中的每个元素代表你在该位置可以跳跃的最大长度.判断你是否能够到达最后一个位置. 示例 1: 输入: ...

  9. 运用NP求解 “跳跃游戏”---计蒜客

    计蒜客里面有一道“跳跃游戏的问题” 给定一个非负整数数组,假定你的初始位置为数组第一个下标. 数组中的每个元素代表你在那个位置能够跳跃的最大长度. 你的目标是到达最后一个下标,并且使用最少的跳跃次数. ...

随机推荐

  1. H5页面跳转到小程序代码

    1.H5页面加代码直接打开小程序 <script type="text/javascript src="https://res.wx.qq.com/open/js/jweix ...

  2. ZOJ - 3870 Team Formation(异或)

    题意:给定N个数,求这N个数中满足A ⊕ B > max{A, B})的AB有多少对.(A,B是N中的某两个数) 分析: 1.异或,首先想到转化为二进制. eg:110011(A)和 1(B)- ...

  3. MySQL日志--二进制日志

    (一)什么是二进制日志 二进制日志(binlog)记录了数据库中所有的DDL和DML操作,但是不包括select语句,语句以"事件"的形式保存,记录了数据库的更改变化,在主从复制( ...

  4. 第二阶段scrum-3

    1.整个团队的任务量: 2.任务看板: 会议照片: 产品状态: 前端制作完成,数据库正在配置

  5. 2016蓝桥杯省赛C/C++A组第三题 方格填数

    题意:如下的10个格子  填入0~9的数字.要求:连续的两个数字不能相邻. (左右.上下.对角都算相邻) 一共有多少种可能的填数方案? 分析:dfs,划定边界,行1~4,列1~3,初始化为INT_IN ...

  6. redis常用命令--基础

    redis默认有个数据库,下标从开始,不支持自定义数据库名字. 使用select  index 切换数据库  : select 7 (切换到第八个数据库) dbsize:求当前数据库中键值对的数量. ...

  7. JZOJ823PJ-C, TG-B

    分身打两场比赛 PJ - C 翻车 T1 原题, 考虑蚂蚁相撞时其实不用管. 然后写个取左右max, 左右min的即可 翻车: 注释freopen后JZOJ不会提示!(大翻车--丢了300分) T2 ...

  8. 18 12 23 html 基本学习

    一个html的基本结构如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  9. VBA代码优化及其他设置操作

    一.代码优化的一些方法 尽量减少在循环中遍历调用对象,公式计算 (操作VBA代码若出现屏幕闪屏,会拖慢运行速度),可以禁止屏幕闪屏.多用在操作工作表/薄,单元格的时候. Application.Scr ...

  10. h5-transform二维变换-扑克牌小案例

    html代码:6张扑克牌 <div class="pkBox"> <img src="../img/pk1.jpg" alt="&q ...