《剑指offer》---丑数

本文算法使用python3实现


1. 问题1

1.1 题目描述:

  把只包含因子2、3和5的数称作丑数(Ugly Number)。判断一个数是否是丑数。
  时间限制:1s;空间限制:32768K


1.2 思路描述:

  大致思路:将该数依次除以 $ 2,3,5 $ ,若最后商为 $ 1 $ 则是丑数,否则,不是丑数。


1.3 程序代码:

class Solution:
	def isUgly(self, num):
		'''判断num是否是丑数'''
		if num <= 0:
			return False
		for i in [2,3,5]:
			while num % i == 0:
				num = num / i
		if num == 1:
			return True
		else:
			return False




2. 问题2

2.1 题目描述:

  把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
  时间限制:1s;空间限制:32768K


2.2 思路描述:

  大致思路
  (1)设置数组 $ UglyNum=[] $ 用来保存丑数。并将 $ 1 $ 添加进数组 $ UglyNum=[1] $。基数设置为 $ 2,3,5 $ 。以基数为质因子的丑数的下标为 $ id2,idx3,idx5 $ ,起始均为 $ 0 $ 。
  (2)计算: $ 2 \times UglyNum[idx2] = 2 \times 1 , 3 \times UglyNum[idx3] = 3 \times 1, 5 \times UglyNum[idx5] = 5 \times 1 $ ,将最小的数存入数组 $ UglyNum =[1,2] $ ,以 $ 2 $ 为基数的丑数下标增加 $ 1 $ : $ idx2 = 0+1 = 1 $ ,其余不变。
  (3)计算: $ 2 \times UglyNum[idx2] = 2 \times 1 , 3 \times UglyNum[idx3] = 3 \times 1 , 5 \times UglyNum[idx5] = 5 \times 1 $ ,将最小的数存入数组 $ UglyNum =[1,2,3] $ ,以 $ 3 $ 为基数的丑数下标增加 $ 1 $ : $ idx3 = 0+1 = 1 $ ,其余不变。
  (4)计算: $ 2 \times UglyNum[idx2] = 2 \times 2 , 3 \times UglyNum[idx3] = 3 \times 2 , 5 \times UglyNum[idx5] = 5 \times 1 $ , 将最小的数存入数组 $ UglyNum =[1,2,3,4] $ ,以 $ 2 $ 为基数的丑数下标增加 $ 1 $ : $ idx2 = 1+1 = 2 $ ,其余不变。
  (5)计算: $ 2 \times UglyNum[idx2] = 2 \times 3 , 3 \times UglyNum[idx3] = 3 \times 2 , 5 \times UglyNum[idx5] = 5 \times 1 $ , 将最小的数存入数组 $ UglyNum =[1,2,3,4,5] $ ,以 $ 5 $ 为基数的丑数下标增加 $ 1 $ : $ idx5 = 0+1 = 1 $ ,其余不变。
  (6)以此类推,计算 $ n-1 $ 次,并将值存入数组中。返回数组最后一个值即为所求。


2.3 程序代码:

class Solution:
	def GetUglyNumber_Solution(self, index):
		'''返回第index个丑数'''
		if index == 0:
			return 0
		# 保存前N个丑数
		uglyNum = [1]
		# 起始下标都为0
		idx2, idx3, idx5 = 0, 0, 0
		# 再存index-1个数即可
		for i in range(index-1):
			n2, n3, n5 = uglyNum[idx2]*2, uglyNum[idx3]*3, uglyNum[idx5]*5
			Min = min(n2, n3, n5)
			uglyNum.append(Min)
			idx2 += (Min == n2)
			idx3 += (Min == n3)
			idx5 += (Min == n5)
		return uglyNum[-1]




3. 问题3

3.1 题目描述:

  有一个列表 $ primes $ ,把只包含因子为列表 $ primes $ 中元素的数称作超级丑数( Super Ugly Number)。例如 当列表为 $ primes = [2,3,5] $ 时,即为问题2。


3.2 思路描述:

  思路同问题二一致。


3.3 程序代码:

class Solution:
	def nthSuperUglyNumber(self, index, primes):
		'''超级丑数
		Args:
			index: n
			primes: 列表
		当某个数的因子只有primes中的元素时,作为超级丑数,求出第n个超级丑数
		'''
		if index == 0 or not primes:
			return 0
		if index == 1:
			return 1
		uglyNum = [1]
		lens = len(primes)
		# idx为列表,保存每次基数下标
		idx = [0] * lens
		# num保存每次乘积值
		num = [0] * lens
		for i in range(index-1):
			# 更新每次乘积值
			for k in range(lens):
				num[k] = uglyNum[idx[k]] * primes[k]
			Min = min(num)
			uglyNum.append(Min)
			# 更新基数下标值
			for k in range(lens):
				idx[k] += (Min == num[k])
		return uglyNum[-1]
posted @ 2018-06-13 19:28  EEEEEcho  阅读(316)  评论(0编辑  收藏  举报