求第1500个丑数

news/2024/10/18 7:47:53/

参考《剑指Offer》

题目:

我们把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。

分析

常规解法

第一反应,我们肯定从1开始遍历,一直到找到第1500个丑数为止,如下:

bool isUgly(int number)  
{  while (number%2==0)  number = number/2;  while (number%3==0)  number = number/3;  while (number%5==0)  number = number/5;  return (number==1)?true:false;  
}  

高效解法:

前面算法之所以效率低,是因为不管一个数是不是丑数都遍历了,我们要尝试找一个只需要计算丑数的方法。
首先,我们再次明确丑数的定义:

丑数是只包含因子2、3和5的数。

那么很容易我们就可以想到,位于前面的丑数,定然是后面的丑数的因子。比如2是4、6、30的因子,3是6、15、27、30的因子。
那么,我们可以通过前面的丑数乘以2、3、5来计算出后面的丑数。
而我们要解决的最主要的问题就是丑数的排序问题。

解决方法:每次找出生成的丑数中大于M的最小值。

首先,我们把已有的丑数都乘以2,找到其中第一个大于M的结果,记作M2。同样的方法乘以3、5,找到的结果记作M3、M5。
最终找到M2、M3、M5中的最小值,就是新生成的最大的丑数,记作新的M。

当然,如果每次都需要对丑数从头到尾的乘以和判断效率是很低的,我们可以用一个数T来记录M的下标。
比如T2,即为M2的下标,在它之前的每一个值乘以2都会小于M,在它之后的每一个值乘以2都会大于M。每次新生成M的时候我们再更新这个T2。
这样我们每次计算M2(乘以2后第一个大于M的数)的时候,只需要让T2后面的一个数乘以2即可了。
T3、T5的生成方式一样。
#代码

#include<iostream>using namespace std;int Min(int n1,int n2,int n3)
{int min=(n1<n2)?n1:n2;min=(min<n3)?min:n3;return min;
}int Solution(int n)
{if(n<=0)return 0;int u[n];u[0]=1;//1为第一个丑数int t2=0;//记录M2的下标int t3=0;int t5=0;for(int i=1;i<n;i++){while(u[t2]*2<=u[i-1])//查找到新的M2,即乘以2后第一个大于M的数t2++;while(u[t3]*3<=u[i-1])t3++;while(u[t5]*5<=u[i-1])t5++;int min=Min(u[t2]*2,u[t3]*3,u[t5]*5);u[i]=min;}return u[n-1];
}int main()
{cout<<Solution(1500)<<endl;return 0;
}

结果

这里写图片描述


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

相关文章

1500行入门linux

文章目录 linux第一章Linux历史版本选择计算机硬件&#xff08;不考&#xff09;计算机软件(不考)系统分区安装实验一交换分区&#xff08;swap&#xff09;手动创建Swap交换分区 /etc/fstab介绍 第二章常用命令索引结点1.文件系统概念&#xff1a;2.Linux的文件系统特性&#…

C++primer(第五版)第一章(开始)

面对八百多页的C圣经《Cprimer》我陷入了沉思。最近终于下定决心把它啃下来&#xff0c;现在打算记录每章的关键点&#xff0c;一是为了巩固知识&#xff0c;二是以后要复习什么的也不用再碰那本砖头。 1.1编写一个简单的C程序 书中给了几行代码: int main() {return 0; } …

为什么MTU普遍值是1500?

原文地址&#xff1a;https://developer.aliyun.com/article/222535 什么是MTU Maximum Transmission Unit&#xff0c;缩写MTU&#xff0c;中文名是&#xff1a;最大传输单元。 这是哪一层网络的概念&#xff1f; 从下面这个表格中可以看到&#xff0c;在7层网络协议中&am…

S7-1200(S7-1500)和S7-1200(S7-1500)不同项目S7通讯

测试内容: 1、 S7-1200(1217)与S7-1200(1214)不同项目S7通讯连接; 2、 S7-1500(ET200SP)与S7-1200(1214)不同项目S7通讯连接; 软件: Step7 V14 SP1 所完成的通讯任务: 1、 S7-1200(S7-1500) CPU (主CPU)将通信数据区DB1(Send)块中的10个字节的数据发送到S7…

1500字节为何成为互联网MTU标准?

以太网无处不在&#xff0c;几乎所有硬件厂商都有涉及&#xff0c;所有以太网链路都有一个共同的参数&#xff1a;MTU。 $ ip l 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWNlink/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: enp5s0: <BROADCAST…

S7-1200和S7-1500数学函数

CALCULATE&#xff1a;计算 可以使用“计算”指令定义并执行表达式&#xff0c;根据所选数据类型计算数学运算或复杂逻辑运算。 可以从指令框的“???”下拉列表中选择该指令的数据类型。根据所选的数据类型&#xff0c;可以组合某些指令的函数以执行复杂计算。将在一个对话…

S7-1200和S7-1500比较操作

CMP &#xff1a;等于 可以使用“等于”指令判断第一个比较值&#xff08;<操作数 1>&#xff09;是否等于第二个比较值&#xff08;<操作数 2>&#xff09;。 如果满足比较条件&#xff0c;则指令返回逻辑运算结果 1。如果不满足比较条件&#xff0c;则指令返回…

1500: 单位转换

1500: 单位转换 1.描述 三师弟最近在复习考研&#xff0c;在复习计算机组成原理的时候&#xff0c;遇到了一个问题。就是在计算机存储里面的单位转换。我们都知道1MB1024KB&#xff0c;1KB1024B&#xff0c;1B8bit&#xff0c;他在做题的时候经常会遇到格式各样的&#xff0c…