【算法题】寻找第K个丑数
来源:互联网 发布:大数据共享交换平台 编辑:程序博客网 时间:2024/05/21 04:43
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
一个丑数C可以写成C=2X*3Y*5Z的形式(其中2X表示2的X次方)。
做法1:
就是从1到M判断每个数x是是不是丑数,一直累加到第N个丑数。在判断一个是数是不是丑数时使用如下方法:1,将x对2一直取余,直到不能取余;2,将余数对3一直取余,直到不能取余;3,将余数对5一直取余,直到不能取余;在1,2,3步骤中若取余的结果为1则结束,结果x是丑数,否则不是。
理论上这种方法是可以计算出第K个丑数的,但是实际上计算量会非常的大
做法2:在得到一个丑数之后可以考虑从之前得到的丑数中得到下一个丑数。假设现在已知的十个丑数,那么第十一个丑数应该是在第十个丑数的基础上得到的。也就是前面十个丑数的某个数乘以2刚好大于第十个数(这里刚好大于第十个数的意思是说这个数前面的数乘以2并不大于第十个丑数),某个数乘以3刚好大于第十个数,某个数乘以5刚好大于第十个数,然后取这三个数中的最小值作为第十一个丑数
int num[k];num[0] = 0;num[1] = 1;int two = 0,three = 0,five = 0;//刚好大于现有最大丑数的三个for(int i = 1; i <= 1499; i++){//每次找出一个丑数 for(int j = 1; j <= i ; j++)//从头向后扫描,若某数的两倍刚好大于上回找出的丑数,将它值记录下来 if((2*num[j-1] <= num[i])&&(2*num[j] > num[i])) two=num[j]*2; for(int j = 1; j <= i ; j++)//从头向后扫描,若某数的三倍刚好大于上回找出的丑数,将它值记录下来 if((3*num[j-1] <= num[i])&&(3*num[j] > num[i])) three=num[j]*3; for(int j = 1; j <= i ; j++)//从头向后扫描,若某数的五倍刚好大于上回找出的丑数,将它值记录下来 if((5*num[j-1] <= num[i])&&(5*num[j] > num[i])) five=num[j]*5; //比较出三个数中最小的 if(two>=three&&five>=three) num[i+1] = three; else if(two>=five&&three>=five) num[i+1] = five; else if(five>=two&&three>=two) num[i+1] = two;}
做法3:
进一步的分析中发现,我们可以在获得最新的丑数时将其之前的状态记录下来,即使用动态规划的思想来获取第k个丑数
解题思路:
如果一个数是丑数,它只能被3或者5或者7整除。因此第k个丑数一定等于3或者5或者7乘以第k个之前的丑数。
求第k个丑数,我们可以从第一个开始求起。默认第一个丑数是1;
第二个丑数:3*1 5*1 7*1中的最小者:3
第三个丑数:3*3(注意3乘以的丑数向后移位一个),5*1,7*1中的最小者:5
第四个丑数:3*3,5*3(后移了一位),7*1中的最小者:7
第五个丑数:3*3,5*3,7*3(后移一位)中的最小者:9
第六个丑数:3*5(后移一位),5*3,7*3中的最小者:15
第七个丑数:3*7(后移一位),5*5(后移一位),7*3中的最小者:21 此时3和5都向后移动。
t2,t3,t5分别记录当前数组中与最末尾的丑数最接近的数(此处的最接近是指:t2最接近末尾丑数x则result[t2]*2最靠近x)。在比较时仅需要比较最靠近末尾丑数的三个值即可。
int UglyNumber(int k){ if(k<7) return k; int t2=0,t3=0,t5=0; vector<int> result(k); result[0]=1; for(int i=1;i<k;++i){ result[i]=min(result[t2]*2,min(result[t3]*3,result[t5]*5)); if(result[i]==result[t2]*2) t2++; if(result[i]==result[t3]*3) t3++; if(result[i]==result[t5]*5) t5++; } return result[k-1];}
- 【算法题】寻找第K个丑数
- 算法题/寻找第K大数
- 寻找第k个丑数
- 寻找第K个丑数
- 寻找第k个丑数
- 算法:寻找第K小元素
- 分治算法--寻找第k大数
- 分治算法寻找第K小数
- 【算法】寻找数组第K大数算法总结
- [编程题] 寻找第K大
- 网易笔试题 寻找第K大
- 寻找第K个数
- 寻找第k大数
- 寻找第k元
- 寻找第K大
- 寻找第K大
- 寻找第K大
- 寻找第K小元素O(N)算法
- html头文件设置常用之<meta>设置缓存
- HTML标签和CSS个人总结
- 集合类
- 第二次课。Java基础
- mybatis学习之路----非代理方式的增删改查用法
- 【算法题】寻找第K个丑数
- 希尔排序
- 成长记录开博
- 【GIT】基本原理和使用操作
- servlet配置load-on-startup的作用
- Java扫雷之Java类的成员属性生命周期的应用。(成员属性生命周期和对象一致)
- JNI引用溢出导致的重启问题分析
- js中typeof的返回值类型有哪些
- Mysql 如何设置字段自动获取当前时间