丑数II
编写一个程序,找出第 n 个丑数。
丑数就是质因数只包含 2, 3, 5 的正整数。
示例:
输入: n = 10 输出: 12 解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。
说明:
1 是丑数。 n 不超过1690。
算法思想
显而易见,我们要找分解式为 2 3 5 构成的数。也容易想到,后面的丑数必然是由前面的丑数乘 2 3 5 得到的。
但是从前往后顺序计算乘积,并且顺序存放的话,例如2*5 3*3
。可以看出先后顺序错位了,10先存放,而9后存放。
因此要取计算的所有乘积的最小值, 这个最小值必然是从小到大的下一个ugly,解决了存放的错位问题。
但是对哪些乘积取最小值呢?
前面的数都计算一遍乘积的话计算量太大
想一下,假如有 2*3, 那么对所有x2,x*3必然没有2*3小,因此对 3 这个因子,只需要计算它和2的乘积即可。后面的肯定不是我们要找的最小乘积。
因此,其实只要为每个因子找到当前最小的乘数即可。
怎么确定每个因子的当前最小乘数呢?
要找当前最小的,首先要确定这个因子的候选乘数有哪些,然后在里面找最小的。
哪些是候选乘数?
我们找当前最小乘数是为了找出下一个最小的丑数。假如要生成所有丑数的话,每个因子都必然要遍历去乘每一个数。
换句话说,对这个因子,所有数都是要乘的,跑不了的,即所有没乘过的数,都是它的候选乘数。
最小的候选乘数
既然所有数都要乘,而我们的数又是从小到大排列的,那么从前往后,第一个没有乘过的就是当前最小乘数。
代码角度来看,即当前乘数为nums[i],每乘一次,即i++,准备乘下一个数即可。
解题代码
注意我们有三个因子,因此需要用三个指针对三个因子维护他们的最小乘数。
1 | class Solution { |