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求解 “跳跃游戏”---计蒜客
计蒜客里面有一道“跳跃游戏的问题” 给定一个非负整数数组,假定你的初始位置为数组第一个下标. 数组中的每个元素代表你在那个位置能够跳跃的最大长度. 你的目标是到达最后一个下标,并且使用最少的跳跃次数. ...
随机推荐
- gdb 常用选项
gdb 常用选项 help:查看命令帮助,具体命令查询在gdb中输入help + 命令,简写h run:重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件),简写r st ...
- 打包|zip
原始:gzip zip -r ./gzip.zip ./gzip/* adding: gzip/split_10.gz (deflated 2%) adding: gzip/split_11.gz ( ...
- 阿里巴巴技术总监全解中台架构19页ppt
//初创时,快速上线 单体架构至少撑了3年 //分布式,中间件基座 //平台化,内部是简单服务,对于业务侧就是快速上线 //平台化之后由于多平台协作问题,再次出现问题: 效率仍然不能匹配业务发展之需要 ...
- RecyclerView+FloatingActionButton应用
一.效果图 二.实现步骤 1.XML布局-添加依赖 <LinearLayout android:id="@+id/layout" android:layout_width=& ...
- Nim游戏(尼姆博弈)
这里是尼姆博弈的模板,前面的博弈问题的博客里也有,这里单列出来. 有N堆石子.A B两个人轮流拿,A先拿.每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜.假设A B都非 ...
- web嵌入到原生的app里需要注意的事项
1.https://www.cnblogs.com/shimily/articles/7943370.html 2.https://www.cnblogs.com/stoneniqiu/p/60771 ...
- POJ 3083:Children of the Candy Corn
Children of the Candy Corn Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11015 Acce ...
- 应用架构的演进--MVC,RPC,SOA,微服务架构
MVC架构:垂直应用架构 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率. 当业务规模很小时,将所有功能都部署在同一个进程中,通过双机或者前置负载均衡 ...
- CI中site_url()和base_url()的区别
CI中site_url()和base_url()的区别 来源:未知 时间:2014-10-20 11:38 阅读数:150 作者:xbdadmin [导读] 在使用CI框架的使用经常碰到 ...
- C#用户控件的使用
1.添加一个用户控件 2.编辑用户控件,相当于自己定义了一个控件,和其他控件一样在窗体中使用,是一个类. 右击项目,生成一下,就可以看到窗体的工具箱上面多了一组工具,可以看到我们定义的控件login ...