【题目描述】
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
【思路解析】 如果遍历所有数,逐个判断是不是丑数,执行取余和除法,时间复杂度较大。采用自下而上的方式,记录从第一个到第n个丑数,牺牲了一定的空间复杂度,来提高时间复杂度。
一个初始数组[1,2,3,4,5,6],包含了几个丑数,再不断向后添加最近的丑数即可。添加下一个丑数的方式就是,从现有的丑数中*2,*3,*5,第一个能够实现乘积大于最后一个丑数的值,取三者中最小的,即为下一个丑数了。
为了节省时间,*2,*3,*5的时候不从第一个丑数开始遍历,用三个指针保存上次的位置,避免了不必要的计算。
【代码】
python:
# -*- coding:utf-8 -*-
class Solution:
def GetUglyNumber_Solution(self, index):
if index==0:
return 0
ugly_list=[1,2,3,4,5,6]
t2,t3,t5=2,1,1
def getmax(t,i,num):
for tt in range(t,i):
max_=ugly_list[tt]*num
if max_>ugly_list[-1]:
t=tt
break
return max_,t
for i in range(6,index):
max2,t2=getmax(t2,i,2)
max3,t3=getmax(t3,i,3)
max5,t5=getmax(t5,i,5)
ugly_list.append(min(max2,max3,max5))
return ugly_list[index-1]
java:
public class Solution {
public int GetUglyNumber_Solution(int index) {
if(index<=6) return index;
int[] result=new int[index];
result[0]=1;
int p2=0,p3=0,p5=0;
for(int i=1;i<index;i++){
result[i]=Math.min(result[p2]*2,Math.min(result[p3]*3,result[p5]*5));
if(result[i] == result[p2]*2)p2++;
if(result[i] == result[p3]*3)p3++;
if(result[i] == result[p5]*5)p5++;
}
return result[index-1];
}
}