3.8 剑指offer 丑数

题目

把只包含质因子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数组的哪一步;“|”表示指针,arr表示丑数数组;
(1)arr 1
|2
|3
|5
目前指针指向0,0,0,队列头arr[0] * 2 = 2, arr[0] * 3 = 3, arr[0] * 5 = 5
(2)arr 1 2
2 |4
|3 6
|5 10
目前指针指向1,0,0,队列头arr[1] * 2 = 4, arr[0] * 3 = 3, arr[0] * 5 = 5
(3)arr 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
………………
转自牛客网讨论区解释:
链接:https://www.nowcoder.com/questionTerminal/6aa9e04fc3794f68acf8778237ba065b

代码

def GetUglyNumber_Solution(index):
    if index <= 0: # 不要忘记判断特殊情况
        return 0
    arr = [1]
    p2 = 0
    p3 = 0
    p5 = 0
    while len(arr) < index:
        minnum = min(arr[p2]*2, arr[p3]*3, arr[p5]*5)
        arr.append(minnum)
        if arr[p2]*2 == minnum:
            p2 += 1
        if arr[p3]*3 == minnum:
            p3 += 1
        if arr[p5]*5 == minnum:
            p5 += 1
    return arr[-1]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DirectX Repair 3.8 是一个用于修复和优化 DirectX 组件的工具。DirectX 是一套由微软开发的多媒体技术集合,用于在 Windows 平台上实现高性能图形、音频和视频的处理。 DirectX Repair 3.8 可以解决一些与 DirectX 相关的系统问题,例如游戏无法正常运行、画面卡顿、声音问题等。它可以自动识别系统中的 DirectX 组件,并检测其中的错误或损坏。然后,它会尝试修复这些问题,使 DirectX 组件恢复正常工作。 使用 DirectX Repair 3.8 修复 DirectX 组件非常简单。首先,我们需要下载并安装该工具。安装完成后,打开程序并点击“开始修复”按钮。工具会开始自动检测并修复 DirectX 组件中的错误。修复过程可能需要一些时间,具体取决于系统中的问题数量和严重程度。 修复完成后,我们可以重新启动电脑,然后再次尝试运行游戏或使用其他需要 DirectX 支持的应用程序。通常情况下,修复后的 DirectX 组件能够解决之前遇到的问题,使我们能够正常享受游戏和其他多媒体内容。 然而,需要注意的是,DirectX Repair 3.8 可能无法解决所有与 DirectX 相关的问题。在某些情况下,问题可能不仅限于 DirectX 组件,可能需要进行进一步的系统维护或修复。此外,由于每个系统的配置和问题不同,使用 DirectX Repair 3.8 修复的效果也会有所不同。 总的来说,DirectX Repair 3.8 是一个方便的工具,用于修复和优化 Windows 平台上的 DirectX 组件。通过使用它,我们可以尝试解决一些与 DirectX 相关的问题,以提高多媒体应用程序的性能和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值