找出丑数
来源:互联网 发布:淘宝五金店铺名字大全 编辑:程序博客网 时间:2024/05/14 04:18
题目:我们只把因子为2、3和5的数称为丑数。求按从小到大的顺序把第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子为7,习惯上吧1当做第一个丑数
直观解法
所谓一个数m是另一个n的因子,是指n能被m整除,也就是n%m==0。
int GetUglyNumber(int index){ int(index<=0){ return 0; } int number=0; int uglyFound=0; while(uglyFound<index){ ++number; if(IsUgly(number)){ ++uglyFound; } } return number;}bool IsUgly(int number){ while(number%2==0) number/=2; while(number%3==0) number/=3; while(number%5==0) number/=5; return (number==1)?true:false;}
这个算法非常直观,代码也十分简洁,但是最大的问题在于每个整数都需要计算,即使一个数字不是丑数,也要对其进行求余和除法操作。该算法的时间复杂度不是很高
创建数组保存已经找到的丑数,用空间换时间的解法
我们可以创建一个数组,里面的数字都是排好序的丑数,每一个丑数都是前面的丑数乘以2、3或者5得到的。
这种思路的关键在于这样确定数组里面的丑数是排好序的。假设数组中已经有若干个丑数排好序后存放到数组中,并且把已有最大的丑数记做M,我们接下来分析如何生成下一个丑数。该丑数肯定是前面某一个丑数乘以2、3、5的结果,所以我们首先考虑把已有的每个丑数乘以2.在乘以2的时候,能得到若干个小于或等于M的结果。由于是按照顺序生成的,小于或者等于M肯定已经在数组中,我们不需要再次考虑,还会得到若干大于M的结果,但是我们只需要第一个大于M的结果,因为我们希望他是从小到大的排序生成的,其他更大的结果以后再说。我们把得到第1个乘以2后大于M的结果记为M2.同样,我们把已有的每一个丑数乘以3和5,能得到第一个大于M的结果M3和M5.那么下一个丑数应该是M2、M3和M5这三个数的最小者
int GerUglyNumber_Solution2(int index){ if (index<=0)return 0; ArrayList<Integer> al = new ArrayList<Integer>(); int count = 1; al.add(1); int min = 0; int m1 = 0, m3 = 0, m5 = 0; while(count < index){ min = min(al.get(m1)*2, al.get(m3)*3, al.get(m5)*5); count++; al.add(min); if(min == al.get(m1)*2) m1++; if(min == al.get(m3)*3) m3++; if(min == al.get(m5)*5) m5++; } return al.get(index - 1); } int min(int number1,int number2,int number3){ int min=(number1<number2)?number1:number2; min=(min<number3)?min:number3; return min; }
第二种思路不需要非丑数的整数上做任何计算,因此时间的效率有明显提升,但是需要空间上的消耗,是空间换时间的一种解法
0 0
- 找出丑数
- 1214迅速地找出丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 丑数
- 设置双坐标轴(twinx & twiny)
- C语言简单运算
- 数字图像处理matlab基本命令
- C++ vector 迭代器失效原因
- Error D8016 '/ZI' and '/Gy-' command-line options are incompatible
- 找出丑数
- 水仙花数_99乘法表
- 链表 实现多项式相加相乘polynomial
- IntelliJ Idea 常用快捷键列表
- bzoj 4712: 洪水 树链剖分
- Android Studio 调用 c c++
- Java Socket通信传输中对象传输问题
- ubuntu环境下安装laravel
- 基于Linux的操作系统实验-Linux基本配置