找出丑数

来源:互联网 发布:淘宝五金店铺名字大全 编辑:程序博客网 时间:2024/05/14 04:18

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

直观解法

所谓一个数m是另一个n的因子,是指n能被m整除,也就是n%m==0。

int GetUglyNumber(int index){ int(index<=0){  return 0; } int number=0; int uglyFound=0; while(uglyFound<index){   ++number;   if(IsUgly(number)){     ++uglyFound;    }  } return number;}bool 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;}

这个算法非常直观,代码也十分简洁,但是最大的问题在于每个整数都需要计算,即使一个数字不是丑数,也要对其进行求余和除法操作。该算法的时间复杂度不是很高

创建数组保存已经找到的丑数,用空间换时间的解法

我们可以创建一个数组,里面的数字都是排好序的丑数,每一个丑数都是前面的丑数乘以2、3或者5得到的。

这种思路的关键在于这样确定数组里面的丑数是排好序的。假设数组中已经有若干个丑数排好序后存放到数组中,并且把已有最大的丑数记做M,我们接下来分析如何生成下一个丑数。该丑数肯定是前面某一个丑数乘以2、3、5的结果,所以我们首先考虑把已有的每个丑数乘以2.在乘以2的时候,能得到若干个小于或等于M的结果。由于是按照顺序生成的,小于或者等于M肯定已经在数组中,我们不需要再次考虑,还会得到若干大于M的结果,但是我们只需要第一个大于M的结果,因为我们希望他是从小到大的排序生成的,其他更大的结果以后再说。我们把得到第1个乘以2后大于M的结果记为M2.同样,我们把已有的每一个丑数乘以3和5,能得到第一个大于M的结果M3和M5.那么下一个丑数应该是M2、M3和M5这三个数的最小者

int GerUglyNumber_Solution2(int index){        if (index<=0)return 0;        ArrayList<Integer> al = new ArrayList<Integer>();        int count = 1;        al.add(1);        int min = 0;        int m1 = 0, m3 = 0, m5 = 0;        while(count < index){            min = min(al.get(m1)*2, al.get(m3)*3, al.get(m5)*5);            count++;            al.add(min);            if(min == al.get(m1)*2)                m1++;            if(min == al.get(m3)*3)                m3++;            if(min == al.get(m5)*5)                m5++;        }        return al.get(index - 1);    }    int min(int number1,int number2,int number3){        int min=(number1<number2)?number1:number2;        min=(min<number3)?min:number3;        return min;    }

第二种思路不需要非丑数的整数上做任何计算,因此时间的效率有明显提升,但是需要空间上的消耗,是空间换时间的一种解法

0 0
原创粉丝点击