丑数35
2016-06-18 17:26
302 查看
题目描述:我们把只包含因子2、3和5的数称作丑数(UglyNumber)。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它含因子7。习惯上我们把1当作第一个丑数。
测试用例:
解题思路:
解法一:对每个数都计算是否为丑数,时间复杂度高,空间消耗少。
a.使用一个函数判断是否为丑数
b.在主函数中对每个数求是否为丑数,并计次。返回要求的第n个丑数。
函数实现:
解法二:使用数组空间,只计算为丑数的数字。时间复杂度低,空间消耗多。
根据丑数的定义,丑数应该是另一个丑数乘以2、3或5得到的数
因此我们可以创建一个数组,里面的数字是排好序的丑数,每一个丑数都是前面的丑数乘以2、3或者5得到的。
如何确保数组里面的丑数是排好序的,对乘2、3或者5之后的丑数比较大小,小者为下一个丑数。
对乘以2而言,肯定存在某一个丑数T2,排在它之前的每一个丑数乘以2得到的结果都会小于已有最大的丑数,在它之后的每一个丑数乘以2得到的结果都会太大。我们只需记下这个丑数的位置,同时每次生成新的丑数的时候,去更新这个T2。对于乘以3和5而言,也存在着同样的T3和T5。
函数实现:
测试用例:
int main(){ //要求的第n个丑数 int n = 1500; //第n个丑数为 int result = UglyNumber(n); //输出结果 std::cout << "The N ugly number is: " << result; //Output: 859963392 return 0; }
解题思路:
解法一:对每个数都计算是否为丑数,时间复杂度高,空间消耗少。
a.使用一个函数判断是否为丑数
b.在主函数中对每个数求是否为丑数,并计次。返回要求的第n个丑数。
函数实现:
//判断数字是否为丑数 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; } //解法一主函数 int UglyNumber(int index){ if(index <= 0) return 0; //数字 int number = 0; //计次 int uglyTimes = 0; while(uglyTimes < index){ ++number; if(IsUgly(number)) uglyTimes++; } return number; }
解法二:使用数组空间,只计算为丑数的数字。时间复杂度低,空间消耗多。
根据丑数的定义,丑数应该是另一个丑数乘以2、3或5得到的数
因此我们可以创建一个数组,里面的数字是排好序的丑数,每一个丑数都是前面的丑数乘以2、3或者5得到的。
如何确保数组里面的丑数是排好序的,对乘2、3或者5之后的丑数比较大小,小者为下一个丑数。
对乘以2而言,肯定存在某一个丑数T2,排在它之前的每一个丑数乘以2得到的结果都会小于已有最大的丑数,在它之后的每一个丑数乘以2得到的结果都会太大。我们只需记下这个丑数的位置,同时每次生成新的丑数的时候,去更新这个T2。对于乘以3和5而言,也存在着同样的T3和T5。
函数实现:
//解法二:效率高,空间消耗多 //三者去最小者 int Min(int n2, int n3, int n5){ if(n2 < n3) return n2 < n5 ? n2 : n5; else return n3 < n5 ? n3 : n5; } int UglyNumber2(int index){ if(index <= 0) return 0; //存放丑数的数组 int *pUglyNumbers = new int[index]; //分配index的容量 //第一个丑数为1 pUglyNumbers[0] = 1; //下一个丑数下标,即第二个 int nextUglyIndex = 1; //保存乘2、3或5数组 int *pMultiply2 = pUglyNumbers; int *pMultiply3 = pUglyNumbers; int *pMultiply5 = pUglyNumbers; while(nextUglyIndex < index){ //当未达到要求的第index个丑数时循环 //当前丑数的最小者 int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5); //将最小者赋值给丑数数组序列的下一个下标位置 pUglyNumbers[nextUglyIndex] = min; //然后检查是否改变位置 while(*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex]) ++pMultiply2;//因为2、3、5初始化的时候是pUglyNumbers, 所以更新位置时会不断追踪下一个丑数位置 while(*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex]) ++pMultiply3; while(*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex]) ++pMultiply5; ++nextUglyIndex; } int ugly = pUglyNumbers[nextUglyIndex - 1]; delete[] pUglyNumbers; return ugly; }
相关文章推荐
- Latin输入法如何添加删除某些语言的输入法
- hdu 5411 CRB and Puzzle【矩阵快速幂】
- Redis 相关学习
- 个人总结
- sql server 带输入输出参数的分页存储过程(效率最高)
- CCD CMOS传感器基本工作原理
- PHP中级程序员常见面试题
- Java远程调试
- Ubuntu 上搭建 Samba 服务器
- 【命令cp】linux cp复制命令参数及用法详解
- bzoj 1513: [POI2006]Tet-Tetris 3D(二维线段树+标记永久化)
- 个人学习笔记---inode节点详解
- 下载B(bilibili)站视频
- [翻译] Linux and the Device Tree
- 获取NVIDIA显卡的温度
- 获取NVIDIA显卡的温度
- @Inject和@Autowired以及@Resource区别
- 获取NVIDIA显卡的温度
- yum源配置方式
- 获取NVIDIA显卡的温度