剑指_49丑数

介绍了两种方法来找出第1500个丑数:第一种方法通过逐个判断每个整数是否为丑数;第二种方法采用动态规划思想,使用数组按顺序保存丑数。

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

有两个解决方法:

第一个,逐个判断每个整数是不是丑数的,对于每个数,判断该数是不是丑数,如果是丑数,那么计数加1,如果不是丑数那么判读下一个数,直到找到第1500个丑数。

丑数是指该数的最小因子只有2,3,5

那么判断一个数是不是丑数的方法就是,如果该数能被2整除,那么将该数除以2,能被3整除,则除以3,能被5整除,则除以5,看最后的数是不是1,如果是1那么该数就是丑数。

    public int GetUglyNumber_Solution(int index) {
        if(index<=0) return 0;
        int number=0;
        int times=0;
        while(times<index){
            ++number;
            if(isUgly(number)){
                ++times;
            }
        }
        return number;
    }
    public boolean 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;
    }

但是这种方法时间复杂度太高,不能ac


第二种方法,用一个数组按照从小到大的顺序保存丑数。

如何依次序的保存丑数,如果当前丑数是M那么它的下一个丑数,肯定是前面所有的丑数中,乘以2恰好大于M的丑数M1,和乘以3恰好大于M的丑数M2,乘以5恰好大于M的丑数M3,中三者最小值min(M1,M2,M3)。

那么接下来如何得到这三个数M1,M2,M3?不用将M数前面的所有数都遍历一遍,分别定义数组中的三个索引,用来指向数组中的数使其该索引位置上的数,乘以2恰好大于M,乘以3恰好大于M,乘以5恰好大于M。

 public int GetUglyNumber_Solution(int index) {
        if(index<=0) return 0;
        int[] numbers=new int[index];
        int p1=0;//指向数组中最小乘以2大于下一个数的位置
        int p2=0;
        int p3=0;
        numbers[0]=1;
        int next=1;
        while(next<index) {
        	numbers[next]=min(numbers[p1]*2,numbers[p2]*3,numbers[p3]*5);
        	while(numbers[p1]*2<=numbers[next]) {//找到下一个大于当前值的索引
        		p1++;
        	}
        	while(numbers[p2]*3<=numbers[next]) p2++;
        	while(numbers[p3]*5<=numbers[next]) p3++;
        	next++;
        }
        return numbers[index-1];
    }
    public int min(int o1,int o2,int o3) {
    	int min=o1<o2?o1:o2;
    	return min<o3?min:o3;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值