剑指offer:丑数

题目描述
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

# -*- 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()

原文地址:https://blog.51cto.com/jayce1111/2419571

时间: 2024-08-29 23:30:55

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