5314跳跃游戏IV
题目:给你一个整数数组 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的更多相关文章
- lintcode: 跳跃游戏 II
跳跃游戏 II 给出一个非负整数数组,你最初定位在数组的第一个位置. 数组中的每个元素代表你在那个位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 样例 给出数组A = ...
- lintcode : 跳跃游戏
跳跃游戏 给出一个非负整数数组,你最初定位在数组的第一个位置. 数组中的每个元素代表你在那个位置可以跳跃的最大长度. 判断你是否能到达数组的最后一个位置. 样例 A = [2,3,1,1,4],返回 ...
- 【LeetCode每天一题】Jump Game II(跳跃游戏II)
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...
- LeetCode(45): 跳跃游戏 II
Hard! 题目描述: 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 示例: 输入: [ ...
- 计蒜客-跳跃游戏二 (简单dp)
题目链接:https://nanti.jisuanke.com/t/20 跳跃游戏二 给定一个非负整数数组,假定你的初始 ...
- [Leetcode]44.跳跃游戏Ⅰ&&45.跳跃游戏Ⅱ
跳跃游戏链接 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] 输出 ...
- 跳跃游戏 12 · Jump Game 12
跳跃游戏 1 [抄题]: [思维问题]: [一句话思路]: [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入): [画图]: [一刷]: 由于要用itera ...
- LeetCode:跳跃游戏【55】
LeetCode:跳跃游戏[55] 题目描述 给定一个非负整数数组,你最初位于数组的第一个位置.数组中的每个元素代表你在该位置可以跳跃的最大长度.判断你是否能够到达最后一个位置. 示例 1: 输入: ...
- 运用NP求解 “跳跃游戏”---计蒜客
计蒜客里面有一道“跳跃游戏的问题” 给定一个非负整数数组,假定你的初始位置为数组第一个下标. 数组中的每个元素代表你在那个位置能够跳跃的最大长度. 你的目标是到达最后一个下标,并且使用最少的跳跃次数. ...
随机推荐
- mybatis配置约束config,mapper
MyBatis 主配置文件 config.xml(这里可以自己起,不过后面带上Config.xml) <?xml version="1.0" encoding="U ...
- 苹果maccms网站漏洞进行修复解决方法教程
上期发现视频名称中包含木马文件 然后教大家使用标签进行过滤 {$vo.vod_name|mac_filter_html} 可是最近发现现在黑客行为是全字段挂马,修改数据字段格式挂马,多重嵌套挂马. 真 ...
- Nginx负载均衡(转发)
http://www.cnblogs.com/jalja/p/6117881.html 一.反向代理 正向代理: 客户端要获取的资源就在服务器上,客户端请求的资源路径就是最终响应资源的服务器路径,这就 ...
- qt 字符串 转换 hex
1. qt 中两个字符的字符串直接转换为 hex,类似于 "1A" 要转换成 16进制的 0x1A,使用 int QString::toInt(bool *ok, int base ...
- i春秋-web-爆破3
首先,是PHP代码审计,看懂就能解出来题. <?php error_reporting(0); session_start(); require('./flag.php'); if(!isset ...
- oo第四单元及课程总结
一.第四单元作业总结 第四单元有两次作业,第十三次作业是实现一个UML类图解析器,可以通过输入一些查询指令来查询一些类图的信息.程序的主干部分已经提供,我们的任务就是实现给出的接口,过程并不繁琐.第十 ...
- 吴裕雄--天生自然Django框架开发笔记:Django 安装
Window 下安装 Django 如果你还未安装Python环境需要先下载Python安装包. 1.Python 下载地址:https://www.python.org/downloads/ 2.D ...
- 尝试用kotlin做一个app(写在前面)
学kotlin的目的好像就是做一个app,不一定有什么想做的项目,只是单纯想掌握这一门技术,确切地说只是单纯想学会做app.对于概念的东西,我也没兴趣深究,用得到的学一下,用不到的,就算了.我也不知道 ...
- 简单makefile示例
Makefile cmd: - g++ 相信在linux下编程的没有不知道makefile的,刚开始学习linux平台下的东西,了解了下makefile的制作,觉得有点东西可以记录下. 下面是一个极其 ...
- chan-vese模型
Python--level set (水平集)和 chan-vese模型 2018年08月28日 10:51:54 GlassySky0816 阅读数:1604 版权声明:本文为博主原创文章,未 ...