《剑指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]

猜你喜欢

转载自www.cnblogs.com/lliuye/p/9179351.html
今日推荐