丑数问题与变种总结
发表声明
1判断丑陋的数量
将因子只包含2、3、5的数称为丑数(Ugly Number ),习惯上将1作为最初的丑数进行面试
lint code 517 uglynumbersegmentfault
剑指正面问题34丑数排列
解法:参考剑指报价,将判断对象按2、3、5的顺序连续整除,最后获得1时,证明该数为丑数; 最优化
//*
*以2、3、5的顺序整除判断(以2、3、5的顺序判断时间最好) ) ) ) ) ) ) ) ) )。
* http://www.lint code.com/zh-cn/problem/ugly-number /
*题意:判断一个数是否是丑陋的数
* @author yzwall
*/
类解决方案{
publicbooleanisugly(intnum ) {
if(num==0) (
返回假;
() ) ) ) )。
if(num==1) {
返回真;
() ) ) ) )。
wile(num%2==0) {
num /=2;
() ) ) ) )。
wile(num%3==0) {
num /=3;
() ) ) ) )。
wile(num%5==0) {
num /=5;
() ) ) ) )。
返回编号==1? 真:假;
() ) ) ) )。
() ) ) ) )。
找到第2k个丑数
lintcode 4 ugly number iies5
剑指正面问题34丑数展开. net
丑数推理
根据丑数的定义,推论如下。
取任意丑数$m$,记录$m2=mtimes2$,$m3=mtimes3$,$m5=mtimes5$code
$m2$、$m3$和$m5$必然是丑数blog
如果$m$是当前的第$n$个丑数,则$m2$、$m3$和$m5$中的最小值必须是第$n 1$个丑数。 队列
2.1解法1:$o(nlogn ) $时间复杂性
丑数推理结果表明,在优先级队列PriorityQueue的开头保存当前第$n$个丑数,用哈希表HashSet保证优先级队列中丑数不重复;
//*
*题意:求第n个丑数
* http://www.lint code.com/zh-cn/problem/ugly-number-ii /
*解法1 :优先队列HashSet求解,时间复杂度O(nlogn )
* @author yzwall
*/
class Solution13 {
publicintnthuglynumber(intn ) {
priorityqueuepq=newpriorityqueue (n,new Comparator ) )
公共公司(Long o2,Long o2 ) {
return o1 o2? -1 : 1;
() ) ) ) )。
);
HashSet hash=new HashSet (;
hash.add(1L );
PQ .出价(1L );
int [ ] primes=new int [ ] { 2,3,5 };
输入主程序3360主程序(for ) {
hash.add () long ) prime;
pq.offer () ) long ) prime;
() ) ) ) )。
长min=primes [0];
for(intI=0; i n; I ) {
//min总是由优先队列保证第i 1个丑数
min=pq.poll (;
输入主程序3360主程序(for ) {
if (! hash.contains(min*prime ) }
hash.add(min*prime );
//HashSet保证优先队列中没有重复丑数
pq.offer(min*prime );
() ) ) ) )。
() ) ) ) )。
() ) ) ) )。
返回(int ) min;
() ) ) ) )。
() ) ) ) )。
2.2解法2:$o(n ) $时间复杂性
根据丑数推理,与解法2.1相比,
对于当前的第$n$个丑数$m$,将找到第一个超过$m$的$m2$,$m3$和$m5$,三者之间的最小者一定是第$n 1$个丑数
用数组保存生成的丑数,避免使用优先队列和哈希表,将时间复杂度优化为$o(n ) $,空间复杂度仍然为$o ) ) n ) $
代码部分参考剑指报价面问题34丑数展开
找到第3k个自定义丑数
自定义丑数的定义为正整数,所有的素数因子都在给定大小为k的素数集合内。
如果将素数集合指定为[ 2,7,13,19 ],则[ 1,2,4,7,8,13,14,16,19,26,28,32 ]将是前12个超丑陋的数字
自定义丑数是广义化的丑数,丑数的素数集合被指定为[ 2,3,5 ]
lintcode 518 siper ugly number
3.1解法1:$o(nlogn ) $时间复杂度
丑数推理,可扩展为自定义丑数:
取任意自定义丑数$m$,指定$primes[]$,${m}_{i}=mtimes primes[i],I=0,1,2,primes.length - 1$
${m}_{i}$必然是自定义丑数;
如果$m$是当前第$n$个丑数,则${m}_{i}$的最小值必须是第$n 1$个自定义丑数。
以上推理结果表明,在优先级队列PriorityQueue的开头保存当前的第$n$个自定义丑数,通过哈希表HashSet保证优先级队列中自定义丑数不重复;
//*
*题意:求第n个自定义丑数
* http://www.lint code.com/zh-cn/problem/super-ugly-number /
*解法1 :优先队列HashSet求解、时间复杂度o(nlogn )、空间复杂度o (n ) )。
* @author yzwall
*/
类解决方案{
publicintnthsuperuglynumber (intn,int[] primes )。
priorityqueuepq=newpriorityqueue (n,new Comparator ) )
公共公司(Long o2,Long o2 ) {
return o1 o2? -1 : 1;
() ) ) ) )。
);
HashSet hash=new HashSet (;
hash.add(1L );
PQ .出价(1L );
输入主程序3360主程序(for ) {
hash.add () long ) prime;
pq.offer () ) long ) prime;
() ) ) ) )。
长min=primes [0];
for(intI=0; i n; I ) {
min=pq.poll (;
输入主程序3360主程序(for ) {
if (! hash.contains(min*prime ) }
hash.add(min*prime );
pq.offer(min*prime );
() ) ) ) )。
() ) ) ) )。
() ) ) ) )。
返回(int ) min;
() ) ) ) )。
() ) ) ) )。