【力扣 - 每日一题】3115. 质数的最大距离(一次遍历、头尾遍历、空间换时间、埃式筛、欧拉筛、打表)Golang实现

原题链接

题目描述

给你一个整数数组 nums。
返回两个(不一定不同的)质数在 nums 中 下标 的 最大距离。

示例 1:

输入: nums = [4,2,9,5,3]
输出: 3
解释: nums[1]、nums[3] 和 nums[4] 是质数。因此答案是 |4 - 1| = 3。

示例 2:

输入: nums = [4,8,2,8]
输出: 0
解释: nums[2] 是质数。因为只有一个质数,所以答案是 |2 - 2| = 0。

提示:

1 < = n u m s . l e n g t h < = 3 ∗ 1 0 5 1 <= nums.length <= 3 * 10^5 1<=nums.length<=3105
1 < = n u m s [ i ] < = 100 1 <= nums[i] <= 100 1<=nums[i]<=100
输入保证 nums 中至少有一个质数。

思路1:一次遍历

函数checkIsPrime用于判断num是否为质数,时间复杂度为 O ( s q r t ( n ) ) O(sqrt(n)) O(sqrt(n))
一次遍历,维护minPos表示最小的质数位置,maxPos表示最大的质数位置,最后maxPos-minPos就是答案
维护的时候,如果该数是质数,更新maxPos;如果minPos未被更新过,即minPos为初始值-1,更新minPos

整体时间复杂度 O ( N ∗ s q r t ( M ) ) O(N*sqrt(M)) O(Nsqrt(M))
代码如下:

func checkIsPrime(num int) bool {if num <= 1 {return false}for i := 2; i*i <= num; i ++ {if num % i == 0 {return false}}return true
}
func maximumPrimeDifference(nums []int) int {minPos,maxPos := -1,-1for idx,elem := range nums {if checkIsPrime(elem) {if minPos == -1 {minPos = idx}maxPos = idx}}return maxPos - minPos
}

在这里插入图片描述

思路2:分别从头尾遍历

在思路1的基础上考虑对maxPos的更新过程进行优化,含义为最大的质数出现的位置,所以倒序遍历找第一个质数即可。
极端情况下,最中间的数是质数,还是会把全部的数都判断一遍。

代码:

func checkIsPrime(num int) bool {if num <= 1 {return false}for i := 2; i*i <= num; i ++ {if num % i == 0 {return false}}return true
}
func maximumPrimeDifference(nums []int) int {minPos,maxPos := -1,-1for idx,elem := range nums {if checkIsPrime(elem) {minPos = idxbreak}}for idx := len(nums) - 1; idx >= 0; idx -- {if checkIsPrime(nums[idx]) {maxPos = idx break}}return maxPos - minPos
}

在这里插入图片描述

思路3:标记结果 空间换时间

在思路1的基础上,考虑有的数如果重复出现的话,会被重复判断。
额外开辟map,存储该数是否为素数,空间换时间。
代码如下:

func checkIsPrime(num int) bool {if num <= 1 {return false}for i := 2; i*i <= num; i ++ {if num % i == 0 {return false}}return true
}
func maximumPrimeDifference(nums []int) int {minPos,maxPos := -1,-1mp := make(map[int]bool,len(nums))for idx,elem := range nums {if flag,ok := mp[elem]; ok {if flag {if minPos == -1 {minPos = idx}maxPos = idx}continue}if checkIsPrime(elem) {if minPos == -1 {minPos = idx}maxPos = idxmp[elem] = true}else{mp[elem] = false}}return maxPos - minPos
}

实际上并没有优化时间,很奇怪
在这里插入图片描述

思路4:埃式筛

可以考虑使用素数筛预处理得到所有质数,其中埃式筛的时间复杂度是 O ( n l o g l o g n ) O(nloglogn) O(nloglogn)

埃式筛优化时间复杂度的原理:

考虑这样一件事情:对于任意一个大于 1 的正整数 n,那么它的 x 倍就是合数(x > 1)。利用这个结论,我们可以避免很多次不必要的检测。
如果我们从小到大考虑每个数,然后同时把当前这个数的所有(比自己大的)倍数记为合数,那么运行结束的时候没有被标记的数就是素数了。

 //埃式筛 
func InitPrime(maxNum int) map[int]struct{} {mp := make(map[int]struct{},maxNum)mp[1]  = struct{}{} //注意特判for i := 2; i <= maxNum; i ++ {if _,ok := mp[i]; ok { continue}for j := 2*i; j <= maxNum; j += i {mp[j] = struct{}{} //非素数}}return mp
}
func maximumPrimeDifference(nums []int) int {maxNum := 0for _,elem := range nums {if maxNum < elem {maxNum = elem}}primeMap := InitPrime(maxNum)minPos,maxPos := -1,-1for idx,elem := range nums {if _,ok := primeMap[elem];!ok {if minPos == -1 {minPos = idx}maxPos = idx}}return maxPos - minPos
}

在这里插入图片描述

思路5:欧拉筛

欧拉筛是在埃氏筛的基础上优化的,时间复杂度为 O ( n ) O(n) O(n)

埃氏筛法仍有优化空间,它会将一个合数重复多次标记。有没有什么办法省掉无意义的步骤呢?答案是肯定的。
如果能让每个合数都只被标记一次,那么时间复杂度就可以降到 O(n) 了。

func InitPrime(maxNum int) map[int]struct{} {mp := make(map[int]struct{},maxNum)mp[1]  = struct{}{} //注意特判primes := make([]int,0,1000)for i := 2; i <= maxNum; i ++ {if _,ok := mp[i]; !ok { primes = append(primes,i)}for j := 0; primes[j] <= maxNum/i; j++ {mp[primes[j]*i] = struct{}{} //非素数if i % primes[j] == 0 {break}}}return mp
}
func maximumPrimeDifference(nums []int) int {maxNum := 0for _,elem := range nums {if maxNum < elem {maxNum = elem}}primeMap := InitPrime(maxNum)minPos,maxPos := -1,-1for idx,elem := range nums {if _,ok := primeMap[elem];!ok {if minPos == -1 {minPos = idx}maxPos = idx}}return maxPos - minPos
}

在这里插入图片描述

思路6: 打表

考虑到 1 < = n u m s [ i ] < = 100 1 <= nums[i] <= 100 1<=nums[i]<=100,100以内的素数个数是有限的,离线把这些数据处理出来

func checkIsPrime(num int) bool {if num <= 1 {return false}for i := 2; i*i <= num; i ++ {if num % i == 0 {return false}}return true
}
func maximumPrimeDifference(nums []int) int {minPos,maxPos := -1,-1primes := []int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}mp := make(map[int]struct{},len(primes))for _,elem := range primes {mp[elem] = struct{}{}}numsLen := len(nums)for idx := 0; idx < numsLen; idx ++ {if _,ok := mp[nums[idx]];ok {minPos = idxbreak}}for idx := numsLen - 1; idx >= 0; idx -- {if _,ok := mp[nums[idx]];ok {maxPos = idxbreak}}return maxPos - minPos
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/40897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法系列--分治排序|再谈快速排序|快速排序的优化|快速选择算法

前言:本文就前期学习快速排序算法的一些疑惑点进行详细解答,并且给出基础快速排序算法的优化版本 一.再谈快速排序 快速排序算法的核心是分治思想,分治策略分为以下三步: 分解:将原问题分解为若干相似,规模较小的子问题解决:如果子问题规模较小,直接解决;否则递归解决子问题合…

策略模式的应用

前言 系统有一个需求就是采购员审批注册供应商的信息时&#xff0c;会生成一个供应商的账号&#xff0c;此时需要发送供应商的账号信息&#xff08;账号、密码&#xff09;到注册填写的邮箱中&#xff0c;通知供应商账号信息&#xff0c;当时很快就写好了一个工具类&#xff0…

Python 学习中什么是字典,如何操作字典?

什么是字典 字典&#xff08;Dictionary&#xff09;是Python中的一种内置数据结构&#xff0c;用于存储键值对&#xff08;key-value pair&#xff09;。字典的特点是通过键来快速查找值&#xff0c;键必须是唯一的&#xff0c;而值可以是任何数据类型。字典在其他编程语言中…

vue实现搜索文章关键字,滑到指定位置并且高亮

1、输入搜索条件&#xff0c;点击搜索按钮 2、滑到定位到指定的搜索条件。 <template><div><div class"search_form"><el-inputv-model"searchVal"placeholder"请输入关键字查询"clearablesize"small"style&quo…

HashMap的底层实现原理详解

HashMap是Java中最常用的集合类之一&#xff0c;其基于哈希表的Map接口实现&#xff0c;提供了快速的键值对存储和检索功能。深入理解HashMap的底层实现原理&#xff0c;对于提升编程技能、应对技术面试以及优化程序性能都具有重要意义。以下从技术难点、面试官关注点、回答吸引…

数据库作业day3

创建一个student表用于存储学生信息 CREATE TABLE student( id INT PRIMARY KEY, name VARCHAR(20) NOT NULL, grade FLOAT ); 向student表中添加一条新记录 记录中id字段的值为1&#xff0c;name字段的值为"monkey"&#xff0c;grade字段的值为98.5 insert into …

对于老百姓而言VR到底能做什么?

VR技术自诞生以来不断发展&#xff0c;已经广泛应用于教育、医疗、工程、军事、航空、航海、影视、娱乐等方面&#xff0c;譬如&#xff0c;大型工程或军事活动VR预演可以大幅度减少人力物力投入&#xff1b;在航空领域&#xff0c;航天飞行员在训练舱中面对屏幕进行各种驾驶操…

mysql修改密码失败报错无法登录解决办法

mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user root@localhost (using password: YES) 这个问题是因为在尝试使用命令行连接MySQL时,使用了明文密码,这是不安全的。同时,由于某种原因,您…

Kylin中的查询引擎:大数据查询加速的引擎解析

Kylin中的查询引擎&#xff1a;大数据查询加速的引擎解析 Apache Kylin是一个开源的分布式分析引擎&#xff0c;专为大规模数据集提供快速的SQL查询和多维分析&#xff08;OLAP&#xff09;能力。在Kylin的架构中&#xff0c;查询引擎&#xff08;Query Engine&#xff09;扮演…

【Linux进阶】文件系统4——文件系统特性

1.磁盘组成与分区的复习 首先说明一下磁盘的物理组成&#xff0c;整块磁盘的组成主要有&#xff1a; 圆形的碟片&#xff08;主要记录数据的部分&#xff09;&#xff1b;机械手臂&#xff0c;与在机械手臂上的磁头&#xff08;可擦写碟片上的数据);主轴马达&#xff0c;可以…

打开浏览器控制台,点击应用,浏览器崩溃

调试的时候&#xff0c;打开控制台&#xff0c;点击 “应用” 立马浏览器奔溃&#xff0c;但是点击别的没问题 调查发现是因为manifest.json这个文件引起的 manifest.json 最主要的原因是因为没有设置这个sizes字段 Google浏览器更新大概到126之后的版本会有问题&#xff0c;之…

AI多模态教程:Qwen-VL多模态大模型实践指南

一、模型介绍 Qwen-VL&#xff0c;由阿里云研发的大规模视觉语言模型&#xff08;Large Vision Language Model, LVLM&#xff09;&#xff0c;代表了人工智能领域的一个重大突破。该模型具有处理和关联图像、文本、检测框等多种类型数据的能力&#xff0c;其输出形式同样多样…

代码随想录Day69(图论Part05)

并查集 // 1.初始化 int fa[MAXN]; void init(int n) {for (int i1;i<n;i)fa[i]i; }// 2.查询 找到的祖先直接返回&#xff0c;未进行路径压缩 int.find(int i){if(fa[i] i)return i;// 递归出口&#xff0c;当到达了祖先位置&#xff0c;就返回祖先elsereturn find(fa[i])…

py基础语法简述

py基础&#xff0c;常用sdk 一些要点 python中是没有常量的关键字的&#xff0c;只是我们常常约定使用大写字符组合的变量名表示常量&#xff0c;也有“不要对其进行赋值”的提醒操作 PI 3.14python3中有六个标准的数据类型&#xff1a; Number(数字)、String(字符串)、Boo…

基于Python爬虫的城市二手房数据分析可视化

基于Python爬虫的城市二手房数据分析可视化 一、前言二、数据采集(爬虫,附完整代码)三、数据可视化(附完整代码)3.1 房源面积-总价散点图3.2 各行政区均价3.3 均价最高的10个小区3.4 均价最高的10个地段3.5 户型分布3.6 词云图四、如何更换城市一、前言 二手房具有价格普…

CSS position属性之relative和absolute

目录 1 参考文章2 五个属性值3 position:static4 position:relative&#xff08;相对&#xff09;5 position:absolute&#xff08;绝对&#xff09; 1 参考文章 https://blog.csdn.net/lalala_dxf/article/details/123566909 https://blog.csdn.net/WangMinGirl/article/deta…

最灵活且易用的C++开源串口通信调试软件

这款C开源串口调试软件&#xff0c;集成了丰富的功能&#xff0c;为用户提供高效、便捷的串口通信调试体验。以下是其核心功能亮点&#xff1a; 基础功能&#xff1a; 数据交互自如&#xff1a;支持串口数据的轻松读取与发送&#xff0c;让数据交换变得简单直接。 灵活配置参…

基于顺序表的通讯录实现

一、前言 基于已经学过的顺序表&#xff0c;可以实现一个简单的通讯录。 二、通讯录相关头文件 //Contact.h #pragma once#define NAME_MAX 20 #define TEL_MAX 20 #define ADDR_MAX 20 #define GENDER_MAX 20typedef struct PersonInfo {char name[NAME_MAX];char gender[G…

Python的招聘数据分析与可视化管理系统-计算机毕业设计源码55218

摘要 随着互联网的迅速发展&#xff0c;招聘数据在规模和复杂性上呈现爆炸式增长&#xff0c;对数据的深入分析和有效可视化成为招聘决策和招聘管理的重要手段。本论文旨在构建一个基于Python的招聘数据分析与可视化管理系统。 该平台以主流招聘平台为数据源&#xff0c;利用Py…

MSPM0G3507——解决printf重定向在其他位置不能用的问题(printf重定向的补充)

除了之前发的文章的printf重定向的代码之外&#xff0c;还要加上这样一段代码即可 int puts(const char *_ptr) {int count fputs(_ptr,stdout);count fputs("\n",stdout);return count;} 完整的重定向&#xff1a; int fputc(int c, FILE* stream) {DL_UART_Main_…