题目描述
把只包含质因子 2 、 3 2、3 2、3和 5 5 5的数称作丑数(Ugly Number)。例如 6 、 8 6、8 6、8都是丑数,但 14 14 14不是,因为它包含质因子 7 7 7。 习惯上我们把 1 1 1当做是第一个丑数。求按从小到大的顺序的第 N N N个丑数。
解题思路
我首先想到的是逆向思维方法:递归方法,写出来后是正确的,由于运行时间比较长,OJ报错;其次使用循环,依旧是运行时间过长,OJ报错。如果给出的index比较大的话,这两种方法在VS2013上面的确耗费了很长时间(下述)。
只能用正向思维的方法来解答此题了(下述)。
什么叫丑数,有且仅有公因子 2 、 3 2、3 2、3或 5 5 5的数称为丑数。也就是任何一个丑数都是由 2 、 3 2、3 2、3或 5 5 5的任意数值和该数值的任意次幂后相乘得来,即 p = 2 x × 3 y × 5 z p=2^x\times3^y\times5^z p=2x×3y×5z 除此之外,不能称为丑数。
首先的想法是定义一个判断是否是丑数的bool函数,即给定一个数,如果是丑数返回true,否则返回false;在此基础上,给定函数中设置循环,注意判断每个数字是否是丑数,返回第N个丑数为止,但这种方法消耗的时间过长,系统没有通过,下面展示具体递归和非递归的代码。
第二种思路:最小的丑数是 1 1 1,则 2 、 3 、 5 2、3、5 2、3、5便是接下来的丑数,它们按照一定的数值乘积求和,逐步迭代,最终按照有由小到大依次排列,就可以得到从小到大的丑数(下述)。
代码实现
1、递归方法
一个数 n n n,当 n = 1 n=1 n=1时,一定是丑数,当 n n n能被 2 2 2整除的时,返回 递归 n / 2 n / 2 n/2,只要能被 2 , 3 , 5 2,3,5 2,3,5整除,就会一直递归将 n n n变成 1 1 1,这个数为丑数;但是一旦出现递归时, n = 7 n=7 n=7这样的情况,说明这个数不是丑数。
这种递归的方法就是将这个数一点一点的进行解剖,就像洋葱一样一层一层的剥开它的心,你会发现,你会讶异,就会发现它最深处的秘密,每次剥掉 2 2 2或 3 3 3或 5 5 5,直到为 1 1 1为止,说明这颗洋葱全都是有 2 、 3 、 5 2、3、5 2、3、5组成的,说明是丑数。
bool IsUglyNumber(int n)
{
if (n == 1)