题目:给你一个整数数组 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. Origin中使用CopyPage复制图片到Word后比例失调解决办法

    Origin画图的优势很多,其图形美观易于操作.对我而言,Origin最大的优点就是与Word兼容,在Origin操作界面空白处直接使用右键CopyPage命令,然后在Word中使用粘贴命令即可插入图 ...

  2. com.alibaba.druid.pool.DruidDataSource

    https://www.cnblogs.com/wuyun-blog/p/5679073.html DRUID介绍 DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0.DBCP.PR ...

  3. POJ 2632:Crashing Robots

    Crashing Robots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8424   Accepted: 3648 D ...

  4. StarUML 3.0.2安装激活

    文章参考:https://blog.csdn.net/sam_shan/article/details/80585240 1.下载StarUML:http://staruml.io/,一直下一步安装. ...

  5. SQL笔记整理

  6. SAP_SD常用事务代码

    1.创建/修改/显示销售订单:VA01/VA02/VA03 2.根据销售订单创建交货单:VL01N 3.修改/显示交货单:VL02N/VL03N 4.交货单发货过账:VL02N 5.发货过账冲销:VL ...

  7. GPU 、APU、CUDA、TPU、FPGA介绍

    购买显卡主要关注:显存.带宽和浮点运算数量   GPU :图形处理器(英语:Graphics Processing Unit,缩写:GPU),又称显示核心.视觉处理器.显示芯片,是一种专门在个人电脑. ...

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

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

  9. shell下32位随机密码生成

    最简单的两个  参考 zzx@zzx120:~$ date | md5sum|cut -c1-790cdbd8 zzx@zzx120:~$ echo  `< /dev/urandom tr -d ...

  10. BZOJ 4033: [HAOI2015]树上染色

    题解: 树形DP 思路,考虑每条边的贡献,即这条边两边的黑点数量相乘+白点数量相乘再成边长 #include<iostream> #include<cstdio> #inclu ...