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

原文地址:https://www.cnblogs.com/lliuye/p/9179351.html

时间: 2024-08-29 09:18:52

《剑指offer》---丑数的相关文章

剑指offer——丑数(c++)

题目描述只包含质因子2.3和5的数称作丑数(UglyNumber).例如6.8都是丑数,但14不是,因为它包含质因子7,习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 思路:1.逐个判断逐个判断每个整数是不是丑数.根据丑数的定义,丑数只能被2,3,5整除,也就是说,如果一个数能被2整除,连续除以2:如果能被3整除,连续除以3:如果能被5整除,连续除以5,如果最后得到1,那么这个数就是丑数,否则就不是. 2.创建数组保存已经找到的丑数第一种方法效率比较低,因为该方法对每个数无论是

剑指Offer——丑数

1.题目描述 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 2.代码实现 public class Solution { public int GetUglyNumber_Solution(int index) { //通过分析可知从1开始的前6个数都是丑数 if (index <= 6) { return index; } /** 通俗易懂的解释: 首先从丑

剑指Offer32 丑数

1 /************************************************************************* 2 > File Name: 32_UglyNumber.c 3 > Author: Juntaran 4 > Mail: [email protected] 5 > Created Time: 2016年09月02日 星期五 12时29分59秒 6 ****************************************

剑指OFFER之丑数(九度OJ1214)

题目描述: 把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7.习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 输入: 输入包括一个整数N(1<=N<=1500). 输出: 可能有多组测试数据,对于每组数据,输出第N个丑数. 样例输入: 3 样例输出: 3 解题思路: 最简单的思路是,从1到大数,每个数都检测一遍是否是丑数,检测方法可以考虑 int ugly(int number){ if(number%2 == 0

【剑指offer】q34:丑数

题目要求第n个丑数,所以对于中间结果不需要保存. def Humble(index): curHum = 1 M2 = 2; M3 = 3; M5 = 5 while index > 1: curHum = min(min(M2, M3), M5) while M2 <= curHum: M2 *= 2 while M3 <= curHum: M3 *= 3 while M5 <= curHum: M5 *= 5 index -= 1 return curHum [剑指offer]

剑指offer (34) 丑数

题目:只包含因子2,3,5的数成为 丑数 求从小到大第1500个丑数 通常我们把1当作第一个丑数 方法一:逐个判断每个整数是不是丑数 如何判断一个数是不是丑数? 根据定义,丑数只能被2,3,5整除,也就是说,这个数的因子中只能是2,3,5 我们不断用这个数除以2,3,5,直到最后,如果得到1,那么这个数就是丑数 bool IsUgly(int num) { assert(num >= 0); while (num % 2 == 0) { num /= 2; } while (num % 3 ==

剑指offer之寻找丑数,待字闺中之序列生成分析

题目来源:剑指offer之寻找丑数 与 待字闺中之序列生成分析 两个题目其实是同一个问题,所有放在一起,算是总结一下,题目如下: 给定一个表达式2^i*2^j,其中i,j为非负整数.请找到一种方法,生成如下序列: 2^0 * 5^0 = 1 2^1 * 5^0 = 2 2^2 * 5^0 = 4 2^0 * 5^1 = 5 2^3 * 5^0 = 8 2^1 * 5^1 = 10 2^4 * 5^0 = 16 2^2 * 5^1 = 20 2^0 * 5^2 = 25 ... ... ... 阅

剑指OFFER之把数组排成最小的数(九度OJ1504)

题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 输入: 输入可能包含多个测试样例.对于每个测试案例,输入的第一行为一个整数m (1<=m <=100)代表输入的正整数的个数.输入的第二行包括m个正整数,其中每个正整数不超过10000000. 输出: 对应每个测试案例,输出m个数字能排成的最小数字. 样例输入: 3 23 13 6 2 23456 56 样

【剑指offer】第一个只出现一次的数

def FirstNotRepeatingChar(string): hashStr = [0] * 256 for c in string: hashStr[ord(c)] += 1 for c in string: if hashStr[ord(c)] == 1: return c 这里说下ord, 可以作为atoi来用,功能是若给定的参数是一个长度为1的字符串,那么若参数是Unicode对象,则返回对应的整数,若为8-bit的string,则返回对应的值. python的帮助文档里举例:

剑指offer 面试题33 把数组排成最小的数

题目链接: 剑指offer 题目链接: 把数组排成最小的数, 例如{3, 32, 321} 输出: 321323 解题思路: 我现在已经知道正确答案了, 就是没有办法去证明, 先去开会, 在开会的时候再去想. 代码: #include <iostream> #include <cstdio> #include <string> #include <vector> #include <cstring> #include <iterator&g