天天看点

***剑指offer-丑数

题目描述,输入一个N,输出第N个丑数。 丑数的意思是质因子是2,3,5的数,规定1是第一个丑数。

思路:既然质因子是2,3,5,  那么一个丑数肯定就只能是2^a*3^b*5^c 的数,a,b,c为指数,丑数乘丑数也依旧是丑数。只要能正确的组合a,b,c,取不同的值,然后可以得到从小到达的丑数,那么题目就容易做出来了。可是怎么才能实现呢。

考虑两个不等式,  对于p,2*p<3*p<5*p,  对于2,不同数p<q,则2*p<2*q。

一开始第一个丑数是1,这时候候选的丑数有 1*2 、1*3、1*5 ,找出他们中最小的,即2,并从候选丑数中剔除2。

此时第二个丑数是2了,这时候候选的丑数有1*3、1*5、2*2、2*3、2*5。若我们不通过上面两个不等式将候选集缩小,则会导致需要比较的数的个数变得非常多,那时间复杂度特别高。此时,观察到1*3<2*3、1*5<2*5所以可以直接剔除后面这两个数。

从而只需要比较2*2 、1*3、1*5了。之后都可以按照这个规则。会发现通过底数或者指数来比较,每次都会剔除到3个数。

java程序:

public class Solution {

    public int GetUglyNumber_Solution(int index) {

        if(index<7)

            return index;

        int[] arr = new int[index];

        arr[0]=1;

        int t1=0,t2=0,t3=0;

        for(int i =1;i<index;i++){

            arr[i]=Math.min(2*arr[t1],Math.min(3*arr[t2],5*arr[t3]));

            if(arr[t1]*2==arr[i])t1++;

            if(arr[t2]*3==arr[i])t2++;

            if(arr[t3]*5==arr[i])t3++;

        }

        return arr[index-1];

    }

}