剑指Offer——丑数

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

import java.lang.Math.*;
public class Solution {
    /*
    思路1:对于从1开始的每个数,都循环的对2,取余数,如果最后的余数不为0 ,则对3循环的取余数
         如果左后的余数不为0 ,则对5取余数,如果最后的余数不为0 ,则该数不是丑数,否则对丑数
         计数的变量count加1。优点是直观且简单,缺点是实现效率低,因为一个数不管是不是丑数都要计算
    思路2:因为丑数只能有2、3、5这三种因子,因此丑数肯定可以分解为两个丑数的乘积,而不能分解为非丑数的
         乘积,因此可以把之前已经找到的丑数保存下来,然后从头开始对每个丑数乘以2、3、5直到找到一个
         大于当前最大丑数的最小值,就是下一个丑数
         但是这样乘下来,当N很大的时候,前面部分的丑数乘以2、3、5都是小于当前丑数的,那么我们可以找到
         一个丑数,在他前面的丑数乘以2都是小于当前丑数的,在他之后的丑数乘以2都是大于当前丑数的,把这
         个数称为T2,同理找到T3、T5,然后这三个数里面最小的就是下一个丑数
         我们用一个数组来存储之前已经找到的丑数,那么T2就是:大于(当前丑数/2)的第一个丑数乘以2,T3,T5同理
    */
    public int GetUglyNumber_Solution(int index) {
        if(index<=0){
            return 0;
        }
        //定义一个整数来对丑数的个数进行计数
        int count = 0;
        //1是第一个丑数
        int uglyNum = 1;
        int t2=0;
        int t3=0;
        int t5=0;
        //用一个数组来保存已经找到的丑数
        int[] uglyNums = new int[index];
        uglyNums[0] = 1;
        while(count<index-1){
            for(int i = 0 ; i<index;i++){
                if(uglyNum/2<uglyNums[i]){
                    t2 = uglyNums[i]*2;
                    break;
                }
            }
            for(int i = 0 ; i<index;i++){
                if(uglyNum/3<uglyNums[i]){
                    t3 = uglyNums[i]*3;
                    break;
                }
            }
            for(int i = 0 ; i<index;i++){
                if(uglyNum/5<uglyNums[i]){
                    t5 = uglyNums[i]*5;
                    break;
                }
            }
            
            uglyNum = t2<t3?t2:t3;
            uglyNum = uglyNum<t5?uglyNum:t5;
            
            count++;
            uglyNums[count] = uglyNum;
        }
        return uglyNum;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值