【LeetCode】263.丑数 264. 丑数 II
I. 263. 丑数(是否为丑数)
一、题目描述
编写一个程序判断给定的数是否为丑数。
丑数就是只包含质因数 2, 3, 5
的正整数。
示例 1:
输入: 6
输出: true
解释: 6 = 2 × 3
示例 2:
输入: 8
输出: true
解释: 8 = 2 × 2 × 2
示例 3:
输入: 14
输出: false
解释: 14 不是丑数,因为它包含了另外一个质因数 7。
说明:
- 1 是丑数。
- 输入不会超过 32 位有符号整数的范围: [ − 2 31 , 2 31 − 1 ] [−2^{31}, 2^{31} − 1] [−231,231−1]。
二、解题思路 & 代码
2.1 循环迭代
class Solution:def isUgly(self, num: int) -> bool:if(num==0):return Falseif(num==1):return Truewhile(num%2==0):num //=2while(num%3==0):num //=3while(num%5==0):num //=5return num==1
2.2 递归
class Solution:def isUgly(self, num: int) -> bool:if(num==0): return Falseif(num==1):return Trueif(num%2==0):return self.isUgly(num // 2)if(num%3==0):return self.isUgly(num // 3)if(num%5==0):return self.isUgly(num // 5)return False
======================================================
II. 264. 丑数(找第 n n n 个丑数)
一、题目描述
写一个程序,找出第 n 个丑数。
丑数就是质因数只包含 2, 3, 5
的正整数。
示例:
输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。
说明:
- 1 是丑数。
- n 不超过1690。
二、解题思路 & 代码
2.1 动态规划
d p [ i ] dp[i] dp[i] 表示第 i 个丑数
前面的每一个数(状态)都可以乘上 2, 3, 5
来形成一个新的状态
创建 3 个指针 p2、p3、p5
,分别表示这 3 个质数因子此时应该乘上第几个状态。
p2、p3、p5 的含义
实际上 p i pi pi 的含义是有资格同 i i i 相乘的最小丑数的位置。
这里资格指的是:如果一个丑数 d p [ p i ] dp[pi] dp[pi] 通过乘以 i i i 可以得到下一个丑数,那么这个丑数 d p [ p i ] dp[pi] dp[pi] 就永远失去了同 i i i 相乘的资格(没有必要再乘了),我们把 p i + + pi++ pi++ 让 d p [ p i ] dp[pi] dp[pi] 指向下一个丑数即可。
举例说明:
- 一开始,丑数只有{1},1可以同 2 、3 、5 相乘,取最小的 1 × 2 = 2 添加到丑数序列中。
- 现在丑数中有 {1,2} ,在上一步中,1 已经同 2 相乘过了,所以今后没必要再比较 1 × 2 了,我们说 1 失去了同 2 相乘的资格。
- 现在 1 有与 3、5 相乘的资格,2 有与 2、3、5 相乘的资格,但是 2 × 3 和 2 × 5 是没必要比较的,因为有比它更小的 1 可以同 3、5 相乘,所以我们只需要比较 1 × 3 、1 × 5 、 2 × 2 。
依此类推,每次我们都分别比较有资格同 2、3、5 相乘的最小丑数,选择最小的那个作为下一个丑数,假设选择到的这个丑数是同 i( i = 2、3、5)相乘得到的,所以它失去了同 i 相乘的资格,把对应的 pi++ ,让 pi 指向下一个丑数即可。
class Solution:def nthUglyNumber(self, n: int) -> int:if( n < 1):return 0p2 = 0p3 = 0p5 = 0dp = [0] * ndp[0] = 1for i in range(1, n):# 比较此时可能的状态,取最小的那个dp[i] = min(dp[p2] * 2, min(dp[p3] * 3, dp[p5] * 5))# 更新指向# 注意这里不能只更新一个指针# 比如 6,可以由 2 * 2 * 2 形成,也可以由 2 * 3 组成if( dp[i] == dp[p2] * 2): p2 += 1if( dp[i] == dp[p3] * 3): p3 += 1if( dp[i] == dp[p5] * 5): p5 += 1return dp[n - 1]
复杂度分析
- 时间复杂度: O(n)。生成一个丑数只需常量时间,所以生成n个丑数需要 O(n)。
- 空间复杂度:O(n)。dp数组的长度为n。
参考:
- 字节跳动面到这道题,有的读者一脸懵逼,有的读者笑嘻嘻
2.2 优先队列(小顶堆)
利用优先队列有自动排序的功能
生成丑数的规律:如果已知丑数 ugly ,那么 ugly * 2,ugly * 3 和 ugly * 5 也都是丑数。
既然求第n小的丑数,可以采用最小堆来解决。每次弹出堆中最小的丑数,然后检查它分别乘以2、3和 5后的数是否生成过,如果是第一次生成,那么就放入堆中。第n个弹出的数即为第n小的丑数。
具体:每次取出队头元素,存入队头元素 *2
、队头元素 *3
、队头元素 *5
但注意,像12
这个元素,可由 4
乘3
得到,也可由6
乘2
得到,所以要注意去重
########################## 比较慢 ################################
# class Solution:
# def nthUglyNumber(self, n: int) -> int:
# c = set()
# m = 1
# stack = [1]
# d = []
# while len(d) < n:
# m = min(stack)
# stack.remove(m)
# d.append(m)
# if m * 2 not in c:
# stack.append(m * 2)
# c.add(m * 2)
# if m * 3 not in c:
# stack.append(m * 3)
# c.add(m * 3)
# if m * 5 not in c:
# stack.append(m * 5)
# c.add(m * 5)
# return d[n - 1]########################## 比较快 ################################
import heapqclass Solution:def nthUglyNumber(self, n: int) -> int:heap = []heapq.heappush(heap, 1)seen = set()seen.add(1)factors = [2, 3, 5]curr_ugly = 1for _ in range(n):curr_ugly = heapq.heappop(heap)for f in factors:new_ugly = curr_ugly * fif new_ugly not in seen:seen.add(new_ugly)heapq.heappush(heap, new_ugly)return curr_ugly
复杂度分析
- 时间复杂度: O(nlog(n))。弹出每个最小值时,时间复杂度都为堆的高度,因此时间复杂度为O(nlog(n)) 。
- 空间复杂度: O(n)。遍历n个丑数,并将每个丑数乘以 2、3 和 5 的结果存入堆中。堆和哈希表的元素个数都不会超过 n * 3。
参考:
- LeetCode题解
【LeetCode】263.丑数 264. 丑数 II相关推荐
- LeetCode 263. 丑数 264. 丑数 II(DP)
文章目录 1. LeetCode 263. 丑数 解题 2. LeetCode 264. 丑数 II DP解题 1. LeetCode 263. 丑数 编写一个程序判断给定的数是否为丑数. 丑数就是只 ...
- leetcode 263, 264, 1201, 313. Ugly Number I, II, III, Super Ugly Number(leetcode 丑数问题合集)
263. Ugly Number https://leetcode.com/problems/ugly-number/ 本题题解由下面的 264. Ugly Number II 改造而来,所以效率会比 ...
- leetcode - 264. 丑数 II
264. 丑数 II -------------------------------------------- 编写一个程序,找出第 n 个丑数. 丑数就是只包含质因数 2, 3, 5 的正整数. 示 ...
- LeetCode 264. 丑数 II
264. 丑数 II Ideas 竟然没想到用小根堆,白学了,再把小根堆抄一遍. Code Python class Solution:def nthUglyNumber(self, n: int) ...
- 86. Leetcode 264. 丑数 II (动态规划-基础题)
给你一个整数 n ,请你找出并返回第 n 个 丑数 .丑数 就是只包含质因数 2.3 和/或 5 的正整数.示例 1:输入:n = 10 输出:12 解释:[1, 2, 3, 4, 5, 6, 8, ...
- 78. Leetcode 264. 丑数 II (堆-技巧二-多路归并)
给你一个整数 n ,请你找出并返回第 n 个 丑数 .丑数 就是只包含质因数 2.3 和/或 5 的正整数.示例 1:输入:n = 10 输出:12 解释:[1, 2, 3, 4, 5, 6, 8, ...
- leetcode 264. 丑数 II(堆)
给你一个整数 n ,请你找出并返回第 n 个 丑数 . 丑数 就是只包含质因数 2.3 和/或 5 的正整数. 示例 1: 输入:n = 10 输出:12 解释:[1, 2, 3, 4, 5, 6, ...
- LeetCode 264.丑数 II(动态规划)
题目描述 编写一个程序,找出第 n 个丑数. 丑数就是只包含质因数 2, 3, 5 的正整数. 示例: 输入: n = 10 输出: 12 解释: 1, 2, 3, 4, 5, 6, 8, 9, 10 ...
- LeetCode 264. 丑数 II--动态规划
丑数 II 编写一个程序,找出第 n 个丑数. 丑数就是质因数只包含 2, 3, 5 的正整数. 示例: 输入: n = 10 输出: 12 解释: 1, 2, 3, 4, 5, 6, 8, 9, 1 ...
最新文章
- 一文详解CMake编译工具与项目构建
- 【性能优化】 之 几种常见的等待事件的演示示例
- Commons里的DButil
- 换股也是一种解套方法
- 5个Linux 服务器发行版你值得拥有
- 让菜鸡讲一讲网络流(isap)
- 算法笔记_面试题_20.数组相关_模板及示例十几道
- python对医学图像的基本处理_python OpenCV 实现图片的医学处理
- Windbg调试工具介绍
- Docer容器客户端在启动的镜像的时候报错Error invoking remote method ‘docker-start-container‘: Error: (HTTP code 500
- 微信小程序云开发——图片展示,视频播放案例
- 计算机进去bios方式,电脑进入BIOS的两种实用方法
- 2022元宇宙十大 “闪光时刻”
- SpringBoot启动时:Process finished with exit code 0解决办法
- 素雅的登录界面,简单而优雅
- 【架构】分布式系统及相关技术栈初了解
- HAL层,.sensors.h 头文件分析
- 王小波经典语录/名句
- 无言以队——需求规格说明书
- 微信朋友圈点赞如何设计测试用例,微信发语音消息,购物车,支付页面如何设计软件测试用例?
热门文章
- [springboot]springboot启动流程
- 学校热水系统服务认证
- 包装类,正则表示式,Arrays类
- 计算机二级vb必背,【2015年必备】全国计算机二级VB公共基础知识总汇(熟记必过,不看后悔).doc...
- 基于ART-PI SPI驱动W25Q128
- web3再牛 也没能逃出这几个老巨头的手掌心
- Unity制作见缝插针小游戏项目实战
- 15、项目:见缝插针游戏---界面
- steam游戏上架流程四:Steamworks SDK 的API 方法回调方式 ( Callback )
- 一点体会:找工作这事儿