题目描述:把只包含因子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;
}
}