面试题 17.09. 第 k 个数[小顶堆][动态规划]
思路
暴力搜索
因为要求的数只含3\5\7这三个素因子,因此只需判断将每个数除3/5/7除尽后是否为1,从而判断是不是所要求序列中的一个数。
超时
代码如下:
class Solution {public int getKthMagicNumber(int k) {int cur = 0, count = 0;int temp;while(count < k){cur++;temp = cur;while(temp % 3 == 0){temp /= 3;}while(temp % 5 == 0){temp /= 5;}while(temp % 7 == 0){temp /= 7;}if(temp == 1){//说明只能被3,5,7整除count++;}}return cur;}
}
小顶堆
通过维护一个小顶堆,堆内元素为对应满足要求的序列,第k个弹出的数就是序列中第k个数,堆初始化时添加元素1
。
当搜索到(弹出)某个数x
时,那么x*3
、x*5
、x*7
肯定是后续序列中一个满足要求的数,将这三个数加入堆中。
需要注意的是,虽然
x
为int
,但是乘以3/5/7后可能会爆,导致负数的出现,使得入堆元素为负数,后续被优先弹出,答案错误。
class Solution {public int getKthMagicNumber(int k) {int[] factors = new int[]{3,5,7};Set<Long> set = new HashSet<>(); //存储已经存在的值PriorityQueue<Long> heap = new PriorityQueue<>();int count = 0;long ans = 1;heap.add(1L);set.add(1L);while(count < k){ans = heap.poll();count++;for(int factor : factors){long newNum = factor * ans;if(!set.contains(newNum)){set.add(newNum);heap.add(newNum);}}}return (int)ans;}
}
动态规划/多指针
参考:
符合题目中条件的数称为丑数。
不难发现,后续的丑数都是由之前的丑数通过乘以因子3/5/7得到的。
如果吧丑数序列称为ugly
,ugly[i]
为第i+1
个丑数(下标从0开始)。考虑以下三个数列:
ugly[0]*3, ugly[1]*3, ugly[2]*3, ugly[3]*3, ......
ugly[0]*5, ugly[1]*5, ugly[2]*5, ugly[3]*5, ......
ugly[0]*7, ugly[1]*7, ugly[2]*7, ugly[3]*7, ......
代入答案中的数列ugly = [1,3,5,7,9, ....]
1*3, 3*3, 5*3, 7*3, 9*3, ......
1*5, 3*5, 5*5, 7*5, 9*5, ......
1*7, 3*7, 5*7, 7*7, 9*7. ......
通过将上述三个数列合并为一个数列就可以得到我们所需要的答案,这其实就是一个合并有序线性表的问题。定义三个指针分别指向上面的三个序列,下一个丑数一定是三个index
代表的值中最小的那个,然后将相应的index++
即可。
当两个指针对应于相同的值,两个指针同时递增。
代码如下
class Solution {//需要注意到的是,每个数都是由之前的数与因子3、5、7相乘得到的。//利用3指针指向对应因子的序列public int getKthMagicNumber(int k) {int[] ans = new int[k+1];// 初始化第一个数为1ans[1] = 1;int p3 = 1, p5 = 1, p7 = 1; //都指向第一个数for (int i = 2; i <= k; i++) {int cur = Math.min(ans[p3]*3, Math.min(ans[p5]*5, ans[p7]*7));ans[i] = cur;if (cur == ans[p3] * 3){p3++;}if (cur == ans[p5] * 5){p5++;}if (cur == ans[p7] * 7){p7++;}}return ans[k];}
}
面试题 17.09. 第 k 个数[小顶堆][动态规划]相关推荐
- leetcode 面试题 17.14. 最小K个数 大顶堆 小顶堆 快排
leetcode 面试题 17.14. 最小K个数 [难度:中等] 设计一个算法,找出数组中最小的k个数.以任意顺序返回这k个数均可. 示例: 输入: arr = [1,3,5,7,2,4,6,8], ...
- ⭐算法入门⭐《堆》中等01 —— LeetCode 面试题 17.09. 第 k 个数
文章目录 一.题目 1.题目描述 2.基础框架 3.原题链接 二.解题报告 1.思路分析 2.时间复杂度 3.代码详解 三.本题小知识 四.加群须知 一.题目 1.题目描述 有些数的素因子只有 3 ...
- 程序员面试金典 - 面试题 17.09. 第 k 个数(set优先队列/DP)
1. 题目 有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数. 注意,不是必须有这些素因子,而是必须不包含其他的素因子. 例如,前几个数按顺序应该是 1,3,5,7,9,15,21. 示 ...
- 力扣 面试题 17.09. 第 k 个数
题目 有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数.注意,不是必须有这些素因子,而是必须不包含其他的素因子.例如,前几个数按顺序应该是 1,3,5,7,9,15,21. 示例 输入: ...
- 【每日一题】 面试题 17.14. 最小K个数
面试题 17.14. 最小K个数
- 面试题 17.14. 最小K个数
面试题 17.14. 最小K个数 设计一个算法,找出数组中最小的k个数.以任意顺序返回这k个数均可. 示例: 输入: arr = [1,3,5,7,2,4,6,8], k = 4 输出: [1,2,3 ...
- 程序员面试金典 - 面试题 17.14. 最小K个数(快排划分O(n))
1. 题目 设计一个算法,找出数组中最小的k个数.以任意顺序返回这k个数均可. 示例: 输入: arr = [1,3,5,7,2,4,6,8], k = 4 输出: [1,2,3,4]提示: 0 &l ...
- 【剑指Offer】最小的k个数---大顶堆 Java
题目:输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 求数组中最小(最大)的n个数通常可以使用大顶堆(小顶堆) ...
- 小k java_leetcode——面试题 17.14. 最小K个数 (java快速排序)
描述:设计一个算法,找出数组中最小的k个数.以任意顺序返回这k个数均可. 输入: arr = [1,3,5,7,2,4,6,8], k = 4 输出: [1,2,3,4] 解题思路: 这题因为不要求排 ...
最新文章
- 怎么去除图像亮度对图像质量评价的影响_图像质量评估指标 SSIM / PSNR / MSE
- db和model用哪个开发大型项目 thinkphp_Java程序员开发大型应用程序时,必须要掌握几个的技巧...
- 快速pow算法c语言_嵌入式必知基础算法(二)
- 【Envi风暴】Envi 5.4遥感影像镶嵌原来如此简单!
- 法国一家夜总会上演机器人钢管舞
- 网络压缩《网络压缩论文整理》
- NAS、SAN和DAS的区别
- java 不刷新页面_java – 更新jsp页面的内容而不刷新
- paip.java 调用c++ dll so总结
- Ubuntu下,远程访问服务器,路径只显示最后打开的文件夹问题
- 安立公司推出CPRI RF 测量选件
- linux 电源管理 power supply class
- html5实现统计功能,基于HTML5的统计图表系统的设计与实现
- 计算机专业网页设计周志,毕业论文(设计)周志范文.doc
- 14.	Zigbee应用程序框架开发指南 - 睡眠设备
- Vasya the Hipster - CodeForces - 581A
- java 上位机 socket_通讯编程上位机软件实现(SOCKET)——第二回
- 惠普电脑如何重装Linux系统,如何把惠普下的Linux操作系统换为windows 7
- Bili狂神说Vue笔记
- p51 thinkpad 拆解_ThinkPad P51硬盘更换指南(图解)
热门文章
- 查询oracle instance,v$instance怎么来的
- unity3d中的网格
- msf生成payload大全
- 盘点:2008年度五大网络营销案例
- 哪个厂家的监控平台用的云服务器_监控云平台
- Macos上的专业加密通讯工具,十分安全。使用了信号协议,该协议结合了预密钥,Double Ratchet算法和3-DH握手信号。
- .net ajax 服务器,以服务器端为中心的 ASP.NET AJAX 模式(2)-陈广琛 | Microsoft Docs
- 【Android 系统】---Android代号、标记、细分版本号
- vue3 项目添加水印的实现方法
- 筑牢国产芯片软件生态,天翼云bcache解决方案来了!