2549. 统计桌面上的不同数字

2023-10-17 06:10

本文主要是介绍2549. 统计桌面上的不同数字,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

题目

题目分析

解题思路1——暴力破解法

解题思路2—— 解决暴力破解法下空间复杂度太高的问题

解题思路3——解决暴力破解法下时间复杂度过高的问题

解题思路4——时空复杂度为O(1)的算法

总结


题目

给你一个正整数 n ,开始时,它放在桌面上。在 10^9 天内,每天都要执行下述步骤:

  • 对于出现在桌面上的每个数字 x ,找出符合 1 <= i <= n 且满足 x % i == 1 的所有数字 i 。
  • 然后,将这些数字放在桌面上。

返回在 10^9 天之后,出现在桌面上的 不同 整数的数目。

注意:

  • 一旦数字放在桌面上,则会一直保留直到结束。
  • % 表示取余运算。例如,14 % 3 等于 2 。

示例 1:

输入:n = 5
输出:4
解释:最开始,5 在桌面上。 
第二天,2 和 4 也出现在桌面上,因为 5 % 2 == 1 且 5 % 4 == 1 。 
再过一天 3 也出现在桌面上,因为 4 % 3 == 1 。 
在十亿天结束时,桌面上的不同数字有 2 、3 、4 、5 。

示例 2:

输入:n = 3 
输出:2
解释: 
因为 3 % 2 == 1 ,2 也出现在桌面上。 
在十亿天结束时,桌面上的不同数字只有两个:2 和 3 。 

提示:

  • 1 <= n <= 100



题目分析

先来分析一下题目的意思:

题目给定了一个正整数n,作为桌面上最先存在的数字。

题目给定了一个天数:10^9,可以理解为循环的次数。

题目也指明了循环体执行的内容:对于桌面上的每一个数字x,找出一个i满足条件:x % i == 1,i∈[1,n],并将找到的这个i放入桌面。

最后要求返回所有循环结束后,桌面上不同数字的个数。


这边需要注意的是,返回的是桌面上不同数字的个数,也就是说如果将桌面上的这些数放入一个集合中,返回的是集合中元素的个数(因为集合中的元素具有不可重复性)。

tip:返回的不是仅出现一次的数字的个数(题目看快了很容易误以为是这个要求)。




解题思路1——暴力破解法

分析完题目后,题目的意思是很简单的,解题流程大致如下:

但是,这样一来,循环次数固定是10^9次,每次可能会产生若干个符合条件的数字放在桌面上,因此代表桌面的数组array的容量和循环次数是处于一个数量级的,这么一来,加上每次循环还要完整遍历一次数组,这时空复杂度想想就恐怖。

因此它虽然可以得到答案,但是这么做必然会产生时间超限或者空间超限的问题。




解题思路2—— 解决暴力破解法下空间复杂度太高的问题

既然暴力破解法下空间复杂度十分的恐怖,那么必然存在一种方法来降低空间复杂度。

此时想到,返回值等价于将桌面看作一个集合时集合中元素的个数,那么集合中元素具有不可重复性的特点,因此,每次将符合条件的数字放入桌面时,首先判断一下桌面中是否已经存在一摸一样的数字,如果存在便不放入桌面,如果不存在再放入桌面,这样一来,便可以很精确地让桌面符合集合的特性,最后返回桌面中元素的个数即可,因为这样一来桌面上的数字必然是互不相等的。

但是,此时并不知道最后集合的容量是多少,因此这么做的话需要借助一些容量可变的容器来存放数字,或者每次放入的时候进行一次数组扩容。

即便这样,空间复杂度也比暴力破解法下降低了不少。

程序的大致流程如下:




解题思路3——解决暴力破解法下时间复杂度过高的问题

接着进行分析。

上面的思路中,虽然降低了空间复杂度的量级,但是并没有对时间复杂度产生太大的影响,因此必须对题目进行再次分析,以寻找降低时间复杂度的方法。

在上面的思路中,可以发现,如果每次都完整遍历集合时,是存在重复操作的,因为n的值由题目中给出,是一个固定值,因此每一轮循环中,i的范围也是固定的,这就导致每一次遍历集合中在上一轮循环中已经访问的元素时,会得到一样的结果,而这些结果必然不会被放入集合中,因此使用在之前循环中已经访问过的数进行计算必然不会对集合产生任何影响,反而会变成存在了大量的无用计算。因此,在一轮循环中,真正需要进行计算的是集合中没有被访问过的元素。

这样一来,就可以给集合的每一个元素设定一个访问标记,每一轮循环只对集合中未被访问过的元素进行计算,当集合中所有的元素都被访问过时,便结束循环,返回集合中元素的个数。

做到这里,整个算法的时间复杂度和空间复杂度已经较暴力破解法大幅下降了。




解题思路4——时空复杂度为O(1)的算法

接着分析下去,题目中有这样一个表达式:

x % i == 1

那么这个表达式便等价于:

(x - 1) % i == 0

即x-1这个数字可以被i整除,也就是说,x-1必然是i的整数倍,即x必然为i的整数倍+1。

也就是这样:

x = factor * i  + 1      其中,factor∈N,i∈[1,n]

那么,当factor = 0,i = 1时,x可以获得最小值1。

但是,就从上面的等式来看,x貌似是没有上限的,但是深入分析一下x:

x的初始值为n,每一次添加进桌面的元素为符合条件的i,而i∈[1,n],因此x的最小值为1,最大值为n。

因此,x存在一个最大值n。

通过上面的分析,可以十分肯定地确定x的范围:x∈[1,n]。

这个结论很有用,但是现在这个结论是没有办法解题的,因为这个范围十分的准确但并不精确。

对于n=1而言,无论循环多少次,1%1永远只会得到一个0(i=1永远不会满足条件),因此对于n=1而言,x永远只有一个元素1。

对于n=2而言,无论循环多少次,2%1永远只会得到一个0(i=1永远不会满足条件),因此对于n=2而言,x永远不可能为1。

对于n=3而言,无论循环多少次,3%1永远只会得到一个0(i=1永远不会满足条件),因此对于n=3而言,x永远不可能为1。

......

对于任意一个值大于1的n而言,无论循环多少次,n%1永远只会得到一个0(i=1永远不会满足条件),因此对于任意一个大于1的n而言,x永远不可能为1。

因此,精确地表示x的范围为:

那么,当n=1时,桌面上不同整数的数目只有1个。当n≥2时,桌面上不同整数的数目最多有n-1个。

 注意这边使用的是最多,因为此时对于n≥2时的情况,并不能直接获得答案。

下面来分析一下这个结论:

当x=2时,不可能获得任何符合条件的i值。

当x=3时,获得的符合条件的i值为2。(3 % 2 = 1)

当x=4时,获得的符合条件的i值为3。(4 % 3 = 1)

当x=5时,获得的符合条件的i值为4和2。(5 % 4 = 1)(5 % 2 = 1)

...

这样看,好像看不出来什么,那么接下来换一种分析方式:

当x=2时,不可能获得任何符合条件的值。

当x=3时,必定存在一个i=2。

当x=4时,必定存在一个i=3。

当x=5时,必定存在一个i=4。

...

当x=n时,必定存在一个i=x-1。

那么,这个结论很有用,使用这个结论,可以接着向下分析:

对于任意一个x=n(n≥3),必然存在i=x-1。(因为n=2时是不存在任何有效的i的)

对于上面得到的n-1,必然由于n-1≠n而可以被添加入集合,因此必然有x=n-1,而此时必然可以得到一个i=x-1=n-2。

而对于上面得到的n-2,必然由于n-2≠n-1≠n而可以被添加入集合,因此必然有x=n-2,而此时必然可以得到一个i=x-1=n-3。

下面以此类推,可以得到:x={n} => x={n,n-1} => x={n,n-1,n-2} => x={n,n-1,n-2,n-3} => x={n,n-1,n-2,n-3,n-4} => ... => x={n,n-1,n-2,n-3,n-4,...,5} =>  x={n,n-1,n-2,n-3,n-4,...,5,4

} => x={n,n-1,n-2,n-3,n-4,...,5,4,3} => x={n,n-1,n-2,n-3,n-4,...,5,4,3,2}

那么,此时可以确定,当n≥2时,集合中的元素个数必定为n-1个。

综上所述:

 到这一步,这一题的最佳解法便是这一个分段函数,这个结论经过缜密的推导而得出。

因此,这一种解法的时空复杂度为O(1)。




总结

这是力扣第330场周赛的第一题,若是可以快速发现此题中存在的数学关系,便可以在很短的时间内写出正确的题解。若是使用暴力破解法,那么便会存在时空超限的问题。

因此对算法的设计很重要。

这篇关于2549. 统计桌面上的不同数字的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/223450

相关文章

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

IDEA与MyEclipse代码量统计方式

《IDEA与MyEclipse代码量统计方式》文章介绍在项目中不安装第三方工具统计代码行数的方法,分别说明MyEclipse通过正则搜索(排除空行和注释)及IDEA使用Statistic插件或调整搜索... 目录项目场景MyEclipse代码量统计IDEA代码量统计总结项目场景在项目中,有时候我们需要统计

Python Flask实现定时任务的不同方法详解

《PythonFlask实现定时任务的不同方法详解》在Flask中实现定时任务,最常用的方法是使用APScheduler库,本文将提供一个完整的解决方案,有需要的小伙伴可以跟随小编一起学习一下... 目录完js整实现方案代码解释1. 依赖安装2. 核心组件3. 任务类型4. 任务管理5. 持久化存储生产环境

基于Python实现数字限制在指定范围内的五种方式

《基于Python实现数字限制在指定范围内的五种方式》在编程中,数字范围限制是常见需求,无论是游戏开发中的角色属性值、金融计算中的利率调整,还是传感器数据处理中的异常值过滤,都需要将数字控制在合理范围... 目录引言一、基础条件判断法二、数学运算巧解法三、装饰器模式法四、自定义类封装法五、NumPy数组处理

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

三频BE12000国补到手2549元! ROG 魔盒Pro WIFI7电竞AI路由器上架

《三频BE12000国补到手2549元!ROG魔盒ProWIFI7电竞AI路由器上架》近日,华硕带来了ROG魔盒ProWIFI7电竞AI路由器(ROGSTRIXGR7Pro),目前新... 华硕推出了ROG 魔盒Pro WIFI7电竞AI路由器(ROG STRIX GR7 Phttp://www.cppcn

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

详解如何使用Python从零开始构建文本统计模型

《详解如何使用Python从零开始构建文本统计模型》在自然语言处理领域,词汇表构建是文本预处理的关键环节,本文通过Python代码实践,演示如何从原始文本中提取多尺度特征,并通过动态调整机制构建更精确... 目录一、项目背景与核心思想二、核心代码解析1. 数据加载与预处理2. 多尺度字符统计3. 统计结果可

Pandas中统计汇总可视化函数plot()的使用

《Pandas中统计汇总可视化函数plot()的使用》Pandas提供了许多强大的数据处理和分析功能,其中plot()函数就是其可视化功能的一个重要组成部分,本文主要介绍了Pandas中统计汇总可视化... 目录一、plot()函数简介二、plot()函数的基本用法三、plot()函数的参数详解四、使用pl