寻找丑数 【微软面试100题 第六十四题】

题目要求:

  我们把只包含因子2、3和5的数称为丑数。例如6、8都是丑数,但是14不是,因为它包含因子7.

  习惯上我们把1当作是第一个丑数。

  求按从小到大的顺序的第1500个丑数。

  参考资料:剑指offer34题。

题目分析:

  方法1 从1开始逐个遍历整数,每个整数如果包含2、3和5中的任何一个因子就除以该因子(包含多个就除以多个,直到不含2、3和5这三个因子),如果这样除得的结果为1,则表示只包含2、3和5,为丑数,此时丑数个数加1,直到个数为1500个。

     缺点是:效率低,不管一个数是不是丑数都要作计算。

  方法2  只计算丑数,后面的丑数根据前面的丑数和2、3、5来得出。计算过程如下图所示:

代码实现:

代码1:

#include <iostream>

using namespace std;

int GetUglyNumbers(int index);

int main(void)
{
    //运行有点慢,需要等一下。可以用GetUglyNumbers(10)来测试。
    cout << "第1500个丑数为:" << GetUglyNumbers(1500) << endl;
    return 0;    
}
bool IsUgly(int number)
{
    while(number%2==0)
        number /= 2;
    while(number%3==0)
        number /= 3;
    while(number%5==0)
        number /=5;
    return (number==1)?true:false;
}
int GetUglyNumbers(int index)
{
    if(index<=0)
        return 0;
    int number = 0;
    int uglyFound = 0;
    while(uglyFound < index)
    {
        number++;
        if(IsUgly(number))
            ++uglyFound;
    }
    return number;
}

代码2:

#include <iostream>

using namespace std;

int GetUglyNumbers(int index);

int main(void)
{
    //相比代码1,运行速度快了很多
    cout << "第1500个丑数为:" << GetUglyNumbers(1500) << endl;
    return 0;    
}
int Min(int num1,int num2,int num3)
{
    int min = (num1<num2)?num1:num2;
    min = (min<num3)?min:num3;
    return min;
}
int GetUglyNumbers(int index)
{
    if(index<=0)
        return 0;
    int *pUglyNumbers = new int[index];
    pUglyNumbers[0] = 1;
    
    int nextUglyIndex = 1;
    int *pUgly2 = pUglyNumbers;
    int *pUgly3 = pUglyNumbers;
    int *pUgly5 = pUglyNumbers;

    while(nextUglyIndex < index)
    {
        int min = Min(*pUgly2*2,*pUgly3*3,*pUgly5*5);
        pUglyNumbers[nextUglyIndex] = min;
        while(*pUgly2*2 <= pUglyNumbers[nextUglyIndex])
            ++pUgly2;
        while(*pUgly3*3 <= pUglyNumbers[nextUglyIndex])
            ++pUgly3;
        while(*pUgly5*5 <= pUglyNumbers[nextUglyIndex])
            ++pUgly5;
        ++nextUglyIndex;
    }
    int ugly = pUglyNumbers[nextUglyIndex-1];
    delete[] pUglyNumbers;
    return ugly;
}
原文地址:https://www.cnblogs.com/tractorman/p/4104492.html