剑指offer-面试题34:丑数

来源:互联网 发布:安卓去视频广告软件 编辑:程序博客网 时间:2024/05/21 13:58

题目:我们把只包含因子2、3、5的数称作丑数。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做第一个丑数。

思路:(1)只包含因子2、3、5,那么用2、3、5除以后必定为1,可以作为丑数的判定标准。从1开始递增数字,每个数都判断是不是丑数,直到找到1500个。这种方法有很大的盲目性,每个数都不断的除以2、3、5效率非常低。

(2)不去判断一个数是不是丑数,而是找出下一个丑数。一个丑数它必定是前面的丑数乘上2或3或5得来的(为什么这样说?因为如果它不是前面的丑数乘上2或3或5,而是乘别的数得来的,那么说明他除了2、3、5还有别的因子,不符合丑数的定义),那么我们每次生成下一个丑数,直到生成1500个。那么被乘的前一个丑数如何确定?它应该满足乘上2或3或5之后刚好比当前已经生成的最大的丑数还要大,而且对2、3、5而言每一个数前面的丑数都是不一样的,每次生成一个丑数即需要更新乘数的位置。

这种算法只花费了额外的一点空间,遍历1500次,每次遍历移动了乘数的的几个指针,比思路1的方法要快得多。

实现代码:

int GetUglyNumber(int n){    if(n < 0)        return 0;            int* UglyNumbers = new int[n];    UglyNumbers[0] = 1;        int* Multiply2 = UglyNumbers;    int* Multiply3 = UglyNumbers;    int* Multiply5 = UglyNumbers;        int NextUglyIndex = 1;    while(NextUglyIndex < n)    {        UglyNumbers[NextUglyIndex] = Min(*Multiply2 * 2, *Multiply3 * 3, *Multiply5 * 5);                while(*Multiply2 * 2 <= UglyNumbers[NextUglyIndex])            ++Multiply2;        while(*Multiply3 * 3 <= UglyNumbers[NextUglyIndex])            ++Multiply3;        while(*Multiply5 * 5 <= UglyNumbers[NextUglyIndex])            ++Multiply5;                    ++NextUglyIndex;    }        int ugly = UglyNumbers[NextUglyIndex - 1];    delete[] UglyNumbers;    return ugly;}int Min(int a, int b, int c){    int tmp = a < b ? a : b;    return tmp < c ? tmp : c;}


0 0
原创粉丝点击