LintCode笔记(8)——丑数II

Ugly number is a number that only have factors 23 and 5.

Design an algorithm to find the nth ugly number. The first 10 ugly numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12...

 Notice

Note that 1 is typically treated as an ugly number.

Example

If n=9, return 10.

Challenge 

O(n log n) or O(n) time.

首先最容易想到的方法就是暴力破解,思路非常简单,首先除2,直到不能整除为止,然后除5到不能整除为止,然后除3直到不能整除为止。最终判断剩余的数字是否为1,如果是1则为丑数,否则不是丑数。

代码如下:

class Solution {
public:
    /*
     * @param n an integer
     * @return the nth prime number as description.
     */
    int nthUglyNumber(int n) {
        // write your code here
        int countN = 0;
        int m = 0;
		int lastNumber = 2;
        while(countN < n)
        {
			m++;
            int number = m;
            while(number % 2 == 0)
                number = number / 2;
            while(number % 3 == 0)
                number = number / 3;
            while(number % 5 == 0)
                number = number / 5;
            if(number == 1)
            {
				countN++;
			}
        }
        return m;
    }
};
但是这样做在LintCode中最后一个测试样例中会因超时提交失败。

第二种方法:

直接寻找丑数,由丑数的定义可知,任何一个丑数都是2^i * 3^j * 5^m这种形式的,因此不断寻找丑数,将他们按从小到大的顺序进行排列,直到第n个即为结果。

首先定义一个数组存放丑数,认为1是丑数,则初始化数组num[0] = 1,然后从2,3,5这三个种子中挑选,选择num[0]*2,num[0]*3,num[0]*5中最小的数为新的丑数,显然应该选择2,即num[1] = 2,然后在从2,3,5中选择,这时应该是从num[1]*2,num[0]*3,num[0]*5中进行选择,显然选择3,即num[2] = 3,然后再从num[1]*2,num[1]*3,num[0]*5中选择最小的,选择2,即num[3] = 4,依次进行如下操作,得到最终的结果。

class Solution {
public:
    /*
     * @param n an integer
     * @return the nth prime number as description.
     */
    int nthUglyNumber(int n) {
        // write your code here
        int *ugly = new int[n];
        ugly[0] = 1;
        int num_2 = 0;
        int num_3 = 0;
        int num_5 = 0;
        for(int i = 1;i<n;i++)
        {
            ugly[i] = min(min(ugly[num_2]*2,ugly[num_3]*3),ugly[num_5]*5);
            if(ugly[i] / ugly[num_2] == 2)
                num_2 ++;
            if(ugly[i] / ugly[num_3] == 3)
                num_3 ++;
            if(ugly[i] / ugly[num_5] == 5)
                num_5 ++;
        }
        return ugly[n-1];
    }
};
代码如上所示,这里需要注意的是

            if(ugly[i] / ugly[num_2] == 2)
                num_2 ++;
            if(ugly[i] / ugly[num_3] == 3)
                num_3 ++;
            if(ugly[i] / ugly[num_5] == 5)
                num_5 ++;
这几段代码的意思是找出到底是2,3,5中哪个种子计算出的ugly[i],当然,有可能有多个种子,比如ugly[num_2]*2 == ugly[num_3]*3时,需要把num_2++,并且要使num_3++。因此这里不能使用if-else,要全部使用if进行判断。


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值