题目描述:求从小到大的第 N 个丑数。丑数是只包含因子 2、3 和 5 的数,习惯 上我们把 1 当做是第一个丑数。
第一种方法:
从1开始判断下一个数是否是丑数,判断标准:
如果能被2整除则,一直除以2,并用商来更新原来的数,直到不能被2整除记下最终所得数为M2
对于M2如果能被3整除,则一直除以3,并用商来更新原来的数,直到无法被3整除,记下最终所得数为M3
对于M3如果能被5整除,则一直除以5,并用商来更新原来的数,直到无法被5整除,记下最终所得数为M5
如果最终的M5==1那么,这个数是丑数,如此下去直到找到第n个丑数为止
这种方法时间复杂度太大
import java.util.ArrayList;
public class Solution {
public int GetUglyNumber_Solution(int index)
{
if (index <= 0)
{
return 0;
}
int number = 0;
int uglyCount = 0;
while (uglyCount < index)
{
number++;
if (IsUgly(number))
{
uglyCount++;
}
}
return number;
}
public boolean 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;
}
}
第二种方法:
充分利用已有丑数的信息,下一个要找的丑数比已有最大丑数刚刚大(用一个例子来演示这个过程比较好理解),这样可以得到一个有序的丑数序列
记录丑数序列a中最大的丑数为M,第一个丑数为1
- 1 a
2 i=0 M2=a[i]*2=2
3 j=0 M3=a[j]*3=3
5 z=0 M5=a[z]*5=5
min(M2,M3,M5)=M2
- 1 2 a
2 4 i=1 M2=a[i]*2=4
3 6 j=0 M3=a[j]*3=3
5 10 z=0 M5=a[z]*5=5
min(M2,M3,M5)=M3=3
- 1 2 3 a
2 4 6 i=1 M2=a[i]*2=4
3 6 9 j=1 M3=6
5 10 15 z=0 M5=5
min(M2,M3,M5)=M2=4
- 1 2 3 4 a
2 4 6 8 i=2 M2=6
3 6 9 12 j=1 M3=6
5 10 15 20 z=0 M5=5
min(M2,M3,M5)=M5=5
…
import java.util.ArrayList;
public class Solution {
public int GetUglyNumber_Solution(int index) {
ArrayList<Integer> out=new ArrayList<Integer>();
out.add(1);
if(index<=0){
return 0;
}
int count=0;
int M2=1,index2=0;
int M3=1,index3=0;
int M5=1,index5=0;
while(count<index){
out.add(Math.min(Math.min(M2,M3),Math.min(M3,M5)));
count++;
while(out.get(index2)*2<=out.get(out.size()-1))
{index2++;}
M2=out.get(index2)*2;
while(out.get(index3)*3<=out.get(out.size()-1))
{index3++;}
M3=out.get(index3)*3;
while(out.get(index5)*5<=out.get(out.size()-1))
{index5++;}
M5=out.get(index5)*5;
}
return out.get(out.size()-1);
}
}