题目信息

  • 时间: 2019-07-03

  • 题目链接:Leetcode

  • tag:动态规划 小根堆

  • 难易程度:中等

  • 题目描述:

    我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。

示例:

输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。

注意

1. 1是丑数
2. n < 1690

解题思路

本题难点

丑数的定义以及查找的方式

具体思路

丑数只包含因子 2,3,5 ,因此有 “丑数 = 某较小丑数 × 某因子” (例如:10=5×2)

设已知长度为 n 的丑数序列 x1,x2,⋯,xn ,求第 n+1 个丑数 xn+1 。根根据递推性质,丑数 x n+1 只可能是以下三种情况其中之一(索引 a,b,c 为未知数):

由于 x n+1 是 最接近 x n的丑数,因此索引 a,b,c 需满足以下条件:

若索引 a,b,c 满足以上条件,则可使用递推公式计算下个丑数 xn+1 ,其为三种情况中的最小值

即:xn+1=min(xa × 2, xb × 3, xc × 5)

动态规划思想:

  • 状态定义:设动态规划列表 dp ,dp[i] 代表第 i+1 个丑数。

  • 转移方程:每轮计算 dp[i] 后,需要更新索引 a,b,c 的值,使其始终满足方程条件。实现方法:分别独立判断 dp[i] 和 dp[a]×2 , dp[b]×3 , dp[c]×5 的大小关系,若相等则将对应索引 a,b,c 加 1 。

注意: dp[0]=1,第一个丑数为 1 ;

代码

class Solution {
public int nthUglyNumber(int n) {
int a = 0, b = 0, c = 0;
int[] dp = new int[n];
//第一个丑数为 1
dp[0] = 1;
for(int i = 1 ; i < n ; i++){
int n2 = 2 * dp[a];
int n3 = 3 * dp[b];
int n5 = 5 * dp[c];
dp[i] = Math.min(Math.min(n2,n3),n5);
if(dp[i] == n2){
a++;
}
if(dp[i] == n3){
b++;
}
if(dp[i] == n5){
c++;
}
}
return dp[n-1];
}
}

复杂度分析:

  • 时间复杂度 O(N) : 其中 N=n ,动态规划需遍历计算 dp列表。
  • 空间复杂度 O(N) : 长度为 N 的 dp 列表使用 O(N)的额外空间。

其他优秀解答

解题思路

小根堆,要去找第n个丑数,首先想到的就是一个个去生成。uglyNum=2^x ∗3^y ∗5^z ,由 1 生成了 2、3、5 ,接着 2、3、5 利用前面公式继续生成。生成过程是先放小的,并且我们需要去重,去重就需要用到 set

代码

class Solution {
public int nthUglyNumber(int n) {
//小根堆
PriorityQueue<Long> pq = new PriorityQueue<>();
Set<Long> s = new HashSet<>();
//初始化,放进堆和set,发现1要开Long数组才可以
long[] primes = new long[]{2, 3, 5};
for (long prime : primes) {
pq.offer(prime);
s.add(prime);
}
long num = 1;
for (int i = 1; i < n; i++) {
num = pq.poll();
//遍历三个因子
for (int j = 0; j < 3; j++) {
if (!s.contains(num * primes[j])) {
pq.offer(num * primes[j]);
s.add(num * primes[j]);
}
}
}
return (int) num;
}
}

每日一题 - 剑指 Offer 49. 丑数的更多相关文章

  1. 剑指 Offer 49. 丑数 + 小根堆 + 动态规划

    剑指 Offer 49. 丑数 Offer_49 题目详情 解法一:小根堆+哈希表/HashSet 根据丑数的定义,如果a是丑数,那么a2, a3以及a*5都是丑数 可以使用小根堆存储按照从小到大排序 ...

  2. 力扣 - 剑指 Offer 49. 丑数

    题目 剑指 Offer 49. 丑数 思路1 丑数是只包含 2.3.5 这三个质因子的数字,同时 1 也是丑数.要计算出 n 之前全部的丑数,就必须将 n 之前的每个丑数都乘以 2.3.5,选取出最小 ...

  3. 【Java】 剑指offer(49) 丑数

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 我们把只包含因子2.3和5的数称作丑数(Ugly Number). ...

  4. [剑指offer] 49. 丑数

    通俗易懂的解释: 首先从丑数的定义我们知道,一个丑数的因子只有2,3,5,那么丑数p = 2 ^ x * 3 ^ y * 5 ^ z,换句话说一个丑数一定由另一个丑数乘以2或者乘以3或者乘以5得到,那 ...

  5. 剑指 Offer 49. 丑数

    题目描述 我们把只包含质因子 2.3 和 5 的数称作丑数(Ugly Number).求按从小到大的顺序的第 n 个丑数. 示例: 输入: n = 10 输出: 12 解释: 1, 2, 3, 4, ...

  6. 【剑指Offer】丑数 解题报告

    [剑指Offer]丑数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题目描述: ...

  7. 【剑指offer】丑数

    把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. leetcode上也 ...

  8. Go语言实现:【剑指offer】丑数

    该题目来源于牛客网<剑指offer>专题. 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7.习惯上我们把1当做是第一个丑 ...

  9. 《剑指offer》丑数

    本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:

随机推荐

  1. Java实现LeetCode_0026_RemoveDuplicatesFromSortedArray

    package javaLeetCode.primary; public class RemoveDuplicatesFromSortedArray_26 { public static void m ...

  2. Java实现复数运算

    1 问题描述 编程实现两个复数的运算.设有两个复数 和 ,则他们的运算公式为: 要求:(1)定义一个结构体类型来描述复数. (2)复数之间的加法.减法.乘法和除法分别用不用的函数来实现. (3)必须使 ...

  3. Java实现回文判断

    1 问题描述 给定一个字符串,如何判断这个字符串是否是回文串? 所谓回文串,是指正读和反读都一样的字符串,如madam.我爱我等. 2 解决方案 解决上述问题,有两种方法可供参考: (1)从字符串两头 ...

  4. java实现巧排扑克牌

    ** 巧排扑克牌** 小明刚上小学,学会了第一个扑克牌"魔术",到处给人表演.魔术的内容是这样的: 他手里握着一叠扑克牌:A,2,-J,Q,K 一共13张.他先自己精心设计它们的顺 ...

  5. Java实现第八届蓝桥杯日期问题

    日期问题 题目描述 小明正在整理一批历史文献.这些历史文献中出现了很多日期.小明知道这些日期都在1960年1月1日至2059年12月31日.令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/ ...

  6. Linux 自动挂载与fstab文件修复

    /etc/fstab文件 自动挂载就是写入/etc/fstab文件 vi /etc/fstab 其中,第九行是/分区的自动挂载信息,有6个字段 第一字段表示分区的UUID(硬盘通用唯一识别码,使用du ...

  7. js事件的一些兼容写法

    事件兼容 事件对象的兼容 获取键码兼容 默认行为兼容 阻止事件冒泡兼容 事件监听兼容 ---- 封装 删除事件监听兼容 ---- 封装 事件委托->获取事件源兼容

  8. Python 图像处理 OpenCV (7):图像平滑(滤波)处理

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  9. 超强教程!在树莓派上构建多节点K8S集群!

    在很长一段时间里,我对于在树莓派上搭建Kubernetes集群极为感兴趣.在网络上找到一些教程并且跟着实操,我已经能够将Kubernetes安装在树莓派上,并在三个Pi集群中工作.然而,在master ...

  10. wdcp如何添加反向代理功能

    1.winscp进入目录 /www/wdlinux/httpd-x.x.x/conf/右键编辑 httpd.conf 这个文件 依次把下面文件名字前面的 # 号去掉 LoadModule proxy_ ...