题目描述
把只包含质因子二、3和5的数称做丑数(Ugly Number)。例如六、8都是丑数,但14不是,由于它包含质因子7。 习惯上咱们把1当作是第一个丑数。求按从小到大的顺序的第N个丑数。git
# -*- coding: utf-8 -*- # @Time : 2019-07-11 23:24 # @Author : Jayce Wong # @ProjectName : job # @FileName : getUglyNumber.py # @Blog : https://blog.51cto.com/jayce1111 # @Github : https://github.com/SysuJayce class Solution: """ 题目中丑数的定义是只包含因子2,3,5的数,特别地,1是第一个丑数。 解法1: 从1开始,逐个判断每一个数字是否是丑数,若是是,则计数器加一,直到找到所要求的第n个丑数为止。 可是这样作的话会对不少非丑数进行计算,时间复杂度过高。 解法2: 定义一个数组,用于按顺序保存已经找到的丑数,再定义三个指针p2, p3, p5,其中p2指向数组中第一个 乘以2以后会比当前数组中末尾元素要大的数字;p3和p5同理。这样,当p2 * 2以后就会比当前最后一个 丑数要大,而当p3 * 3 以后也会比最后一个丑数要大, p5同理。这样,当前最后一个丑数以后的第一个 丑数就出如今p2 * 2, p3 * 3, p5 * 5之间,咱们只须要比较这三个数的大小便可找到下一个丑数。 注意每找到一个这样的丑数以后咱们就要更新p2, p3, p5,直到咱们找到足够多的丑数。 这种方法是以空间换时间,咱们维护了一个长度为n的数组,并最终返回这个数组的末尾元素。 """ def GetUglyNumber_Solution(self, index): if index <= 0: return 0 uglyNumbers = [1] * index # 用于保存已找到丑数的数组 p2 = p3 = p5 = 0 idx = 1 while idx < index: # 每次都这三个数中找一个最小的做为下一个丑数 nextUglyNumber = min(uglyNumbers[p2] * 2, uglyNumbers[p3] * 3, uglyNumbers[p5] * 5) uglyNumbers[idx] = nextUglyNumber # 而后更新这三个指针 while uglyNumbers[p2] * 2 <= nextUglyNumber: p2 += 1 while uglyNumbers[p3] * 3 <= nextUglyNumber: p3 += 1 while uglyNumbers[p5] * 5 <= nextUglyNumber: p5 += 1 idx += 1 return uglyNumbers[index - 1] def main(): solution = Solution() index = 1 print(solution.GetUglyNumber_Solution(index)) if __name__ == '__main__': main()