LeetCode题解——Ugly Number II

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.

最简单的想法是:从1开始逐个数判断是否是丑数,如果是计数器加1,直到找到第K个丑数;这种方式会判断大量的非丑数,耗时太大。

更直接的想法:直接找丑数:第一个丑数为1,找到第二个比1大的丑数为2,第三个比2的丑数为3,第三个比3的丑数为4.....通过一定的法则,每次计算出下一个最小的丑数。只需要计算K次,耗时大量减少。

假设数组UglyNumbers中已经有了M个丑数,把已有的每个丑数都分别乘以2,3,5。然后从中找到最小的比UglyNumbers[M-1]大的数即为下一个丑数。然而这其中仍有有很多不必要的计算。事实上,对乘以2而言,肯定存在某一个丑数T2,排在它前面的每一个丑数乘以2得到的结果都会小于已有最大的丑数UglyNumbers[M-1];排在它之后的每一个丑数乘以2得到的结果都会太大。我们只需记下这个丑数的位置,同时每次生成新的丑数的时候,去更新这个T2。对乘以3和乘以5而言,也存在着同样的问题。

<pre name="code" class="cpp">
 
 
class Solution {
public:
    int nthUglyNumber(int n) {
        if(n<=0) return 0;
        int *UglyNumbers=new int[n];//存储前n个找到的uglynumber,每次找一个最小的uglynumber
        UglyNumbers[0]=1;
        int *pMutiply2 = UglyNumbers;
        int *pMutiply3 = UglyNumbers;
        int *pMutiply5 = UglyNumbers;
        int i = 1;
        while(i<n){
            int NextUglyNumber = Min(*pMutiply2*2,*pMutiply3*3,*pMutiply5*5);
            UglyNumbers[i]= NextUglyNumber;
            while(*pMutiply2*2<=NextUglyNumber) ++pMutiply2;
            while(*pMutiply3*3<=NextUglyNumber) ++pMutiply3;
            while(*pMutiply5*5<=NextUglyNumber) ++pMutiply5;
            ++i;
        }

        int ans = UglyNumbers[n-1];
        delete[] UglyNumbers;
        return ans;
    }
    int Min(int a,int b,int c){
        return (a<=b && a<=c)?a:((b<=c?b:c));
    }
};


你可能感兴趣的:(LeetCode,number,丑数,Ugly)