【多次过】Lintcode 4. 丑数 II

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/majichen95/article/details/82049503

设计一个算法,找出只含素因子235 的第 n 小的数。

符合条件的数如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12...

样例

如果n = 9, 返回 10

挑战

要求时间复杂度为O(nlogn)或者O(n)

注意事项

我们可以认为1也是一个丑数


解题思路:

暴力解法不做介绍大家都可以想到,在该题会time limited。换一种思路是:所有的肯定都是由2,3,5这三个数组成(1不算),则可以理解为后面的数由前面的数与2,3,5组合而成的。

如果 Ugly Number: 1, 2, 3, 4, 5, 6, 8, 10, ..........

那么 1*2 2*2 3*2 4*2 5*2 6*2 8*2 10*2 ...........*2

        1*3 2*3 3*3 4*3 5*3 6*3 8*3 10*3 .......... *3

        1*5 2*5 3*5 4*5 5*5 6*5 8*5 10*5 .......... *5

都是Ugly Number。产生下一个Ugly Number的方法则是选出ugly[num2]*2 , ugly[num3]*3 , ugly[num5]*5中最小的一个,得到丑数后,在相应的丑数因子计数器上+1 以便于寻找下一个更大的丑数。

只要不断把新产生的ugly number添加到ugly number数组中就可以了,直到找到第N个。

public class Solution {
    /**
     * @param n: An integer
     * @return: the nth prime number as description.
     */
    public int nthUglyNumber(int n) {
        // write your code here
        int[] ugly = new int[n];
        ugly[0] = 1;
        
        //定义因子计数器
        int num2 = 0;
        int num3 = 0;
        int num5 = 0;
        
        for(int i=1 ; i<n ; i++){
            //新丑数是2,3,5倍数中最小
            ugly[i] = getMin(ugly[num2]*2 , ugly[num3]*3 , ugly[num5]*5);
            //判断新存放的丑数是2,3,5中的哪个数的倍数
            //并在相应的倍数计数器+1,使得与因子相乘的数值变化,得到新的丑数
            if(ugly[i] == ugly[num2]*2)
                num2++;
            if(ugly[i] == ugly[num3]*3)
                num3++;   
            if(ugly[i] == ugly[num5]*5)
                num5++;
        }
        
        return ugly[n-1];
    }
    
    public static int getMin(int num1 , int num2 , int num3){
        int temp = num1 < num2 ? num1 : num2;
        return temp < num3 ? temp : num3;
    }
}

猜你喜欢

转载自blog.csdn.net/majichen95/article/details/82049503