题目

Write a program to find the n-th ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.

Note that 1 is typically treated as an ugly number.

方法一

思路

由于上一篇文章《Ugly Number》中实现了判断一个正整数是否是Ugly Number的功能,所以,我们从1开始,逐一判断正整数是否是Ugly Number,如果是,i 加一,直到 i 等于 n 即可。

这个算法的缺点是开销太大,我们不仅需要找出第n个Ugly Number之前的所有Ugly Number,也需要找出第n个Ugly Number之前的所有Ugly Number。方法二的思路是只要找到第n个Ugly Number之前的所有Ugly Number即可。

代码

class Solution {
public:
    int nthUglyNumber(int n) {
        int i = 0;
        int num = 1;
        while (i != n)
        {
            if (isUgly(num) )
            {
                i++;
            }
            num++;
        }
        return num - 1;
    }
    
    bool isUgly(int num) {
        if (num <= 0)
        {
            return false;
        }
        
        if (1 == num)
        {
            return true;
        }
            
        int pNum = num;
        
        while (pNum % 5 == 0)
        {
            pNum /= 5;
        }
        while (pNum % 3 == 0)
        {
            pNum /= 3;
        }
        while (pNum % 2 == 0)
        {
            pNum /= 2;
        }
        
        if (pNum == 1)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
};

方法二

思路

如何只找Ugly Number呢?我们从它的概念入手。Ugly Number的prime factors只有1,2,3,5,也就是说所有的Ugly Number都是由一个或多个1,2,3,5的乘积组成,这样,我们就从1开始派生,对于目前已知的Ugly Number(初始状态Ugly Number只有一个“1”),让它分别乘以2,3,5,得到的数还是Ugly Number。

考虑到我们需要从小到大提取前n个Ugly Number,set 容器很符合我们的要求,它不仅能自动排序,而且能屏蔽掉相同元素。

看!下面代码就是这么简洁!

代码

class Solution {
public:
    long nthUglyNumber(int n) {
        int i = 1;
        set<long> s;
        s.insert(1);
        while (i < n)
        {
            long first = *s.begin();
            s.insert(first * 2);
            s.insert(first * 3);
            s.insert(first * 5);
            
            s.erase(first);
            
            i++;
        }
        
        return *s.begin();
    }
};

总结

此题一个坑爹的地方是:网站给出的函数的返回值明明是int型,测试数据却用到了long型,结果因为数据越界报出“Wrong Answer”的错误,这怪我喽?通过的方法是将 nthUglyNumber 函数的返回值改为long即可。


chenhong2018
2 声望0 粉丝

« 上一篇
Ugly Number
下一篇 »
H-Index