[leetcode]jump-game-iv

news/2024/10/21 10:08:26/

. - 力扣(LeetCode)

给你一个整数数组 arr ,你一开始在数组的第一个元素处(下标为 0)。

每一步,你可以从下标 i 跳到下标 i + 1 、i - 1 或者 j :

  • i + 1 需满足:i + 1 < arr.length
  • i - 1 需满足:i - 1 >= 0
  • j 需满足:arr[i] == arr[j] 且 i != j

请你返回到达数组最后一个元素的下标处所需的 最少操作次数 。

注意:任何时候你都不能跳到数组外面。

示例 1:

输入:arr = [100,-23,-23,404,100,23,23,23,3,404]
输出:3
解释:那你需要跳跃 3 次,下标依次为 0 --> 4 --> 3 --> 9 。下标 9 为数组的最后一个元素的下标。

示例 2:

输入:arr = [7]
输出:0
解释:一开始就在最后一个元素处,所以你不需要跳跃。

示例 3:

输入:arr = [7,6,9,6,9,6,9,7]
输出:1
解释:你可以直接从下标 0 处跳到下标 7 处,也就是数组的最后一个元素处。

提示:

  • 1 <= arr.length <= 5 * 104
  • -108 <= arr[i] <= 108

方法一:广度优先搜索
思路

记数组 arr\textit{arr}arr 的长度为 nnn。题目描述的数组可以抽象为一个无向图,数组元素为图的顶点,相邻下标的元素之间有一条无向边相连,所有值相同元素之间也有无向边相连。每条边的权重都为 111,即此图为无权图。求从第一个元素到最后一个元素的最少操作数,即求从第一个元素到最后一个元素的最短路径长度。求无权图两点间的最短路可以用广度优先搜索来解,时间复杂度为 O(V+E)O(V+E)O(V+E),其中 VVV 为图的顶点数,EEE 为图的边数。

在此题中,V=nV = nV=n,而 EEE 可达 O(n2)O(n^2)O(n 
2
 ) 数量级,按照常规方法使用广度优先搜索会超时。造成超时的主要原因是所有值相同的元素构成了一个稠密子图,普通的广度优先搜索方法会对这个稠密子图中的所有边都访问一次。但对于无权图的最短路问题,这样的访问是不必要的。在第一次访问到这个子图中的某个节点时,即会将这个子图的所有其他未在队列中的节点都放入队列。在第二次访问到这个子图中的节点时,就不需要去考虑这个子图中的其他节点了,因为所有其他节点都已经在队列中或者已经被访问过了。因此,在用广度优先搜索解决此题时,先需要找出所有的值相同的子图,用一个哈希表 idxSameValue\textit{idxSameValue}idxSameValue 保存。在第一次把这个子图的所有节点放入队列后,把该子图清空,就不会重复访问该子图的其他边了。

class Solution {
public:int minJumps(vector<int>& arr) {unordered_map<int, vector<int>> idxSameValue;for (int i = 0; i < arr.size(); i++) {idxSameValue[arr[i]].push_back(i);}unordered_set<int> visitedIndex;queue<pair<int, int>> q;q.emplace(0, 0);visitedIndex.emplace(0);while (!q.empty()) {auto [idx, step] = q.front();q.pop();if (idx == arr.size() - 1) {return step;}int v = arr[idx];step++;if (idxSameValue.count(v)) {for (auto & i : idxSameValue[v]) {if (!visitedIndex.count(i)) {visitedIndex.emplace(i);q.emplace(i, step);}}idxSameValue.erase(v);}if (idx + 1 < arr.size() && !visitedIndex.count(idx + 1)) {visitedIndex.emplace(idx + 1);q.emplace(idx + 1, step);}if (idx - 1 >= 0 && !visitedIndex.count(idx - 1)) {visitedIndex.emplace(idx - 1);q.emplace(idx - 1, step);}}return -1;}
};


http://www.ppmy.cn/news/1436899.html

相关文章

go语言并发实战——日志收集系统(四) 利用tail包实现对日志文件的实时监控

Linux中的tail命令 tail 命令是一个在 Unix/Linux 操作系统上用来显示文件末尾内容的命令。它可以显示文件的最后几行内容&#xff0c;默认情况下显示文件的最后 10 行。tail 命令 非常有用&#xff0c;特别是在我们查看日志文件或者监视文件变化时。 基本用法如下&#xff1a…

npm镜像源的查看和切换

前言 原域名https://registry.npm.taobao.org/ 原来的淘宝镜像已经不行了,当npm去taobao时,会出现一个证书过期的提示. 下面的是最新的地址: 切换到淘宝镜像(最新的地址) #最新地址 淘宝 NPM 镜像站喊你切换新域名啦! npm config set registry https://registry.npmmirror.com…

MyCat 数据库中间件

一、介绍 1、单数据库进行数据存储的问题&#xff1a; IO瓶颈&#xff1a;热点数据太多&#xff0c;数据库缓存不足以容纳这些热点数据&#xff0c;产生大量磁盘IO&#xff0c;效率较低。 CPU瓶颈&#xff1a;排序、分组、连接查询、聚合统计等SQL会耗费大量的CPU资源。 2、…

解释一下“暂存区”的概念,在Git中它扮演什么角色?

文章目录 暂存区在Git中的概念与作用什么是暂存区&#xff08;Staging Area&#xff09;暂存区的位置和结构 暂存区在Git工作流程中的角色1. 分离工作区与版本库的交互示例代码与操作步骤示例1&#xff1a;将工作区的修改添加至暂存区 2. 控制提交内容的粒度示例2&#xff1a;分…

C++修炼之路之多态---多态的原理(虚函数表)

目录 一&#xff1a;多态的原理 1.虚函数表 2.原理分析 3.对于虚表存在哪里的探讨 4.对于是不是所有的虚函数都要存进虚函数表的探讨 二&#xff1a;多继承中的虚函数表 三&#xff1a;常见的问答题 接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗--…

Linux 修改远程默认端口-22

1 编辑sshd配置&#xff0c;修改默认的端口 vi /etc/ssh/sshd_config #添加新的端口 port 62222 ps&#xff1a;先添加新的端口&#xff0c;用新端口能远程登录后再注销22端口&#xff0c;防止修改有问题&#xff0c;导致22端口也不能远程登录 2 重启sshd /etc/init.d/sshd r…

java 项目中日志规范处理和异常规范处理问题

在 Java 中&#xff0c;可以使用全局异常处理器&#xff08;Global Exception Handler&#xff09;来集中处理异常。要实现全局异常处理&#xff0c;需要创建一个类并使用 ControllerAdvice 注解标记该类&#xff0c;然后在该类中定义一个或多个方法&#xff0c;并使用 Excepti…

帮助中心系统搭建不再是难题,这几个工具来帮你

在面临客户服务挑战时&#xff0c;有效的帮助中心系统是提升用户满意度和解决问题效率的关键。幸运的是&#xff0c;搭建一个功能全面的帮助中心不再是什么难事。下面&#xff0c;我要为你介绍三款能够帮忙打造帮助中心的超实用工具&#xff0c;让你的客户支持体验迅速升级。 1…