丑数

思路:设定初始丑数列表,每次寻找最近的一个丑数。

由于丑数的因子只能是2,3,5,所以需要将list中所有已知丑数乘以2,3,5,然后所有候选中大于当前最大丑数的最小丑数就是下一个丑数。

为了提高效率,被判断出已经在当前列表的元素,不需要重复计算。

import java.util.*;

public class Solution {
    public int minNumber(int a,int b){
        return a<=b?a:b;
    }
    public int GetUglyNumber_Solution(int index) {
        if(index<=0) return 0;
        //初始化丑数存储list
        index-=1;
        ArrayList<Integer> UglyNumbers=new ArrayList<>();
        UglyNumbers.add(1);
        UglyNumbers.add(2);
        UglyNumbers.add(3);
        UglyNumbers.add(4);
        UglyNumbers.add(5);
        int length=UglyNumbers.size();
        //初始化几个参数
        int M2index=0,M3index=0,M5index=0;
        int M2=0,M3=0,M5=0;
        int maxUglyNum=5,nextUglyNum=0;
        //begin
        if(index<length) return UglyNumbers.get(index);

        while(length-1<index){
            //乘2的丑数候选处理
            while(M2index<length&&M2<=maxUglyNum){
                M2=2*UglyNumbers.get(M2index++);
            }
            if(M2index<length) M2index--;
            else return 0;//异常返回
            //乘3的丑数候选处理
            while(M3index<length&&M3<=maxUglyNum){
                M3=3*UglyNumbers.get(M3index++);
            }
            if(M3index<length) M3index--;
            else return 0;//异常返回
            //乘5的丑数候选处理
            while(M5index<length&&M5<=maxUglyNum){
                M5=5*UglyNumbers.get(M5index++);
            }
            if(M5index<length) M5index--;
            else return 0;//异常返回
            //获得下一个丑数
            nextUglyNum=minNumber(minNumber(M2,M3),M5);
            //三个指针分别移动
            if(nextUglyNum==M2){
                M2index++;
            }
            if(nextUglyNum==M3){
                M3index++;
            }
            if(nextUglyNum==M5){
                M5index++;
            }
            //更新list
            UglyNumbers.add(nextUglyNum);
            length=UglyNumbers.size();
            maxUglyNum=nextUglyNum;
            M2=0;M3=0;M5=0;
        }
        return nextUglyNum;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值