【两次过】Lintcode 4. 丑数 II

博客围绕设计算法找出只含素因子2、3、5的第n小的数展开。提到挑战是将时间复杂度控制在O(nlogn)或O(n),指出暴力解法会超时。采用新思路,认为丑数由前面的数与2、3、5组合而成,类似动态规划,不断添加新丑数到数组直至找到第N个。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计一个算法,找出只含素因子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个。

有一丝动态规划的解法,数组ugly[i]代表第i+1个丑数,由题意得ugly[i]能从上一个丑数*2或*3或*5得到,选出其中的最小值即为当前丑数。

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;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值