【剑指offer】丑数 python/Java

1,553 阅读1分钟

【题目描述】

把只包含质因子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];
    }
}