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


通俗易懂的解释:

首先从丑数的定义我们知道,一个丑数的因子只有2,3,5,那么丑数p = 2 ^ x * 3 ^ y * 5 ^ z,换句话说一个丑数一定由另一个丑数乘以2或者乘以3或者乘以5得到,那么我们从1开始乘以2,3,5,就得到2,3,5三个丑数,在从这三个丑数出发乘以2,3,5就得到4,6,10,6,9,15,10,15,25九个丑数,我们发现这种方法会得到重复的丑数,而且我们题目要求第N个丑数,这样的方法得到的丑数也是无序的。那么我们可以维护三个队列:

(1)丑数数组: 1

乘以2的队列:2

乘以3的队列:3

乘以5的队列:5

选择三个队列头最小的数2加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;

(2)丑数数组:1,2

乘以2的队列:4

乘以3的队列:3,6

乘以5的队列:5,10

选择三个队列头最小的数3加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;

(3)丑数数组:1,2,3

乘以2的队列:4,6

乘以3的队列:6,9

乘以5的队列:5,10,15

选择三个队列头里最小的数4加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;

(4)丑数数组:1,2,3,4

乘以2的队列:6,8

乘以3的队列:6,9,12

乘以5的队列:5,10,15,20

选择三个队列头里最小的数5加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;

(5)丑数数组:1,2,3,4,5

乘以2的队列:6,8,10,

乘以3的队列:6,9,12,15

乘以5的队列:10,15,20,25

选择三个队列头里最小的数6加入丑数数组,但我们发现,有两个队列头都为6,所以我们弹出两个队列头,同时将12,18,30放入三个队列;

……………………

疑问:

1.为什么分三个队列?

丑数数组里的数一定是有序的,因为我们是从丑数数组里的数乘以2,3,5选出的最小数,一定比以前未乘以2,3,5大,同时对于三个队列内部,按先后顺序乘以2,3,5分别放入,所以同一个队列内部也是有序的;

2.为什么比较三个队列头部最小的数放入丑数数组?

因为三个队列是有序的,所以取出三个头中最小的,等同于找到了三个队列所有数中最小的。

实现思路:

我们没有必要维护三个队列,只需要记录三个指针显示到达哪一步;“|”表示指针,arr表示丑数数组;

(1)1

|2

|3

|5

目前指针指向0,0,0,队列头arr[0] * 2 = 2,  arr[0] * 3 = 3,  arr[0] * 5 = 5

(2)1 2

2 |4

|3 6

|5 10

目前指针指向1,0,0,队列头arr[1] * 2 = 4,  arr[0] * 3 = 3, arr[0] * 5 = 5

(3)1 2 3

2| 4 6

3 |6 9

|5 10 15

目前指针指向1,1,0,队列头arr[1] * 2 = 4,  arr[1] * 3 = 6, arr[0] * 5 = 5

………………


代码:

class Solution {
public:int GetUglyNumber_Solution(int index) {// 0-6的丑数分别为0-6if(index < 7) return index;//p2,p3,p5分别为三个队列的指针,newNum为从队列头选出来的最小数int p2 = 0, p3 = 0, p5 = 0, newNum = 1;vector<int> arr;arr.push_back(newNum);while(arr.size() < index) {//选出三个队列头最小的数newNum = min(arr[p2] * 2, min(arr[p3] * 3, arr[p5] * 5));//这三个if有可能进入一个或者多个,进入多个是三个队列头最小的数有多个的情况if(arr[p2] * 2 == newNum) p2++;if(arr[p3] * 3 == newNum) p3++;if(arr[p5] * 5 == newNum) p5++;arr.push_back(newNum);}return newNum;}
};

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

  1. 【leetcode】 剑指 Offer学习计划(java版本含注释)(上)

    目录 前言 第一天(栈与队列) 剑指 Offer 09. 用两个栈实现队列(简单) 剑指 Offer 30. 包含min函数的栈(简单) 第二天(链表) 剑指 Offer 06. 从尾到头打印链表(简 ...

  2. 剑指offer:丑数

    题目描述 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 解题思 ...

  3. 剑指offer(26-33题)详解

    文章目录 26 二叉搜索树与双向链表 27 字符串的排列 28 数字中出现次数超过一半的数字(待优化)★ 29 最小的K个数 30 连续子数组最大和 31 整数中1出现的次数 32 把数组排成最小的数 ...

  4. 《剑指offer》-- 把数组排成最小的数、丑数、二进制中1的个数、表示数值的字符串、替换空格

    一.把数组排成最小的数: 1.题目: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为 ...

  5. 剑指offer之31-35题解

    剑指offer之31-35题解 目录 整数中1出现的次数(从1到n整数中1出现的次数) 把数组排成最小的数 丑数 第一个只出现一次的字符位置 数组中的逆序对 31. 整数中1出现的次数(从1到n整数中 ...

  6. 牛客网剑指offer编程实践31-40题

    31. 整数中1出现的次数(从1到n整数中1出现的次数) 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12. ...

  7. 剑指offer(刷题31-40)--c++,Python版本

    文章目录 目录 第31 题: 解题思路: 代码实现: c++ python 第32题: 解题思路: 代码实现: c++ python 第33题: 解题思路: 代码实现: c++ python 第34题 ...

  8. 剑指Offer丑数问题

    这是剑指第一次卡死我的题--记录一下 首先看题目: 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7. 习惯上我们把1当做是第一个丑数 ...

  9. 剑指offer 手刷python 汇总整理版本~

    文章目录 0.递归&脑力 斐波那契数列 数值的n次方 二分法和牛顿迭代法求平方根 丑数 正则表达式匹配 [LeetCode#42. Trapping Rain Water 收集雨水](http ...

最新文章

  1. 从OpenStack Newton发布看开源云计算
  2. (原创)c#学习笔记05--变量的更多内容01--类型转换01--隐式转换
  3. 【图像超分辨率】Understanding Deformable Alignment in Video Super-Resolution
  4. Git分支操作与远程仓库的使用
  5. IOS开发之格式化日期时间
  6. @tap和@click的区别_计算属性---uview工作笔记001
  7. 8051 r0-r7 是什么
  8. LR11安装报错:此计算机上缺少vc2005_sp1_with_atl_fix_redist,请安装所有缺少的必要组件,然后重新运行此安装。
  9. 无标度网络和小世界网络的区别
  10. cs224n课后作业
  11. Excel·VBA单元格区域行列数转换函数
  12. windows2008R2 TSL1.0升级成1.2的解决方案
  13. c语言写字机器人,写字机器人(基于STM32简易实现)
  14. TIA博途_基于SCL语言制作模拟量输入输出全局库的具体方法
  15. 华为手机不小心点了始终_华为手机有一个设置,用过一次就再也离不开了,你打开了吗?...
  16. python三维曲面拟合_用Python拟合多项式曲面
  17. Python基于pyzbar、opencv、pyqt5库,实现二维码识别 gui 应用程序开发
  18. 裸辞接单第一个月的收入
  19. 【今日CV 计算机视觉论文速览 第140期】Wed, 3 Jul 2019
  20. 《野兽绅士》总结2——斗士都有自己的全金属外壳

热门文章

  1. ubuntu -- 安装memcached
  2. 通知公告阅读日志构建说明
  3. 实现将一个字符串转化成对应的整形数字
  4. java图形界面应用程序(转)
  5. cisco SMD 配置安装
  6. linux线程同步(1)-互斥量
  7. Linux编译动态链接库
  8. 【机器学习入门笔记12:matplotlib绘图模块的使用】20190217
  9. mybatis支持驼峰自动转换sql吗_mybatis-plus返回map自动转驼峰配置操作
  10. 怎么测试本地网页在不同分辨率下电脑显示效果_干货:微信小程序测试过程中的各个要点...