''' 题目描述 把只包含质因子2、3和5的数称作丑数(Ugly Number)。 例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。 跟跳台阶的问题很相似,如果想要获得第N个丑数,就必须要一直计算到N个 ''' ''' 题目描述 把只包含质因子2、3和5的数称作丑数(Ugly Number)。 例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。 思路一: 逐步判断每个自然数是不是丑数(这样带来的时间按复杂度很大) 您的代码已保存 运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。 思路二: 答案给出的精妙解法: 假设已知当前的丑数序列为:[1,2,3,4,5] 则后序填充丑数序列所使用的数值必然出自于对于当前丑数序列中的数值乘以:2,3,5 只是按照一定顺序排列,故而当前的任务是需要找到有当前丑数列表中的元素所产生的(不再列表中的)最小丑数值 给定3个指针索引下标:index_2,index_3,index_5,分别表示当前需要乘以相应因子的丑数(在当前的丑数列表中) 初始情况下:index_2,index_3,index_5 相等,都指向位置position index=0 对于index_2,从当前的index_2开始遍历列表,找到第一个乘以2能够大于list[-1]的丑数因子,即数值3,index_2=2 可能是下一个丑数的数值为6 对于index_3,从当前的index_3开始遍历列表,找到第一个乘以3能够大于list[-1]的丑数因子,即数值2,index_2=1 可能是下一个丑数的数值为6 对于index_5,从当前的index_5开始遍历列表,找到第一个乘以5能够大于list[-1]的丑数因子,即数值2,index_5=1 可能是下一个丑数的数值为10 而最小的丑数是6, 更新后的丑数列表[1,2,3,4,5,6] index_2=2 index_2=1 index_5=1 进行下一次循环 ''' class Solution: def is_ulgy(self,num): # 判断一个自然数是不是丑数 # print('here',num) while (num % 2 == 0): num = num // 2 while (num % 3 == 0): num = num // 3 while (num % 5 == 0): num = num // 5 if num==1: return True else: return False def GetUglyNumber_Solution(self, index): # print(index) # write code here factor = [1, 2, 3, 4, 5] if index <= len(factor): return factor[index - 1] last = index - len(factor) start = 5 # print(last) while(last): # print(last) start=start+1 # 从小到大遍历自然数,判断每个数值是不是丑数,如果当前的数值是丑数,则last数值减1 # 从6开始 # print('here',self.is_ulgy(6)) while(1): if(self.is_ulgy(start)): break else: start += 1 last -= 1 return start if __name__=='__main__': print(Solution().GetUglyNumber_Solution(1))#1 print(Solution().GetUglyNumber_Solution(10))# 12 print(Solution().GetUglyNumber_Solution(400))#311040 import time start=time.time() print(Solution().GetUglyNumber_Solution(1500)) end=time.time() print('calculating',end-start)# 非常慢 class Solution: def GetUglyNumber_Solution(self, index): # write code here factor = [1, 2, 3, 4, 5] if index==0: return 0 if index <= len(factor): return factor[index - 1] index_2=0 index_3=0 index_5=0 last=index-len(factor) while(last): temp=[] for can_2 in range(index_2,len(factor)): if factor[can_2]*2>factor[-1]: temp.append(factor[can_2]*2) index_2=can_2 break for can_3 in range(index_3,len(factor)): if factor[can_3]*3>factor[-1]: temp.append(factor[can_3]*3) index_3=can_3 break for can_5 in range(index_5,len(factor)): if factor[can_5]*5>factor[-1]: temp.append(factor[can_5]*5) index_5=can_5 break factor.append(min(temp)) last-=1 return factor[-1] # 对于优化后的代码 if __name__=='__main__': print(Solution().GetUglyNumber_Solution(1))#1 print(Solution().GetUglyNumber_Solution(10))# 12 print(Solution().GetUglyNumber_Solution(400))#311040 import time start=time.time() print(Solution().GetUglyNumber_Solution(1500)) end=time.time() print('calculating',end-start) ''' 1 12 311040 859963392 calculating 0.0060062408447265625 '''