程序员面试金典: 9.7数学与概率 7.7有些数的素因子只有3,5,7,请设计一个算法,找出其中第k个数
2017-01-06 00:55
2621 查看
#include <iostream> #include <stdio.h> using namespace std; /* 问题:有些数的素因子只有3,5,7,请设计一个算法,找出其中第k个数。 分析:第k个数是指第k小的数吧?这个题目应该是剑指offer或编程之美中的丑数。 丑数的关键是寻找下一个丑数, 下一个丑数 = 在之前生成的丑数数组中寻找一个数 * (3或5或7),即大于当前丑数的最小值 设当前丑数为M 设第一个乘以3大于M的数为M3,同理M5,M7,则M = min(M3, M5 , M7) 对于丑数3而言,必定存在T3使得T3之前的数乘以3都小于M,T3之后的丑数 关键是寻找丑数数组中第一个乘以3大于当前最大丑数的数T3,寻找丑数数组中第一个乘以5大于最大丑数的数T5,同理T7 使得: 设当前丑数为M 3*T3=M3 > M 【公式(1)】 5*T5=M5 > M 【公式(2)】 7*T7=M7 > M 【公式(3)】 从中令新的M = min(M3 , M5 , M7),并更新T3,T5,T7,使得新的T3,有3*T3 > M,同理T5,T7 【操作1】 如果不更新,带来的问题就是,会陷入死循环 比如刚开始M=1,初始T3=T5=T7=1,满足上述条件后,M=3,此时3*T3 <= M,则T3=1没有等于3,同理后续T5=1,T7=1,而M=7, 之后就发现T3,T5,T7中没有一个能符合上述公式(1),(2),(3),则M一直变成7不再变化; 为了防止这种情况,要进行上述操作1的处理,为的就是能够作为下一个丑数M的候选值能够一直变大 输入: 7(k) 输出: 25 关键: 1 下一个丑数 = 在之前生成的丑数数组中寻找一个数 * (3或5或7),即大于当前丑数的最小值 设当前丑数为M 3*T3=M3 > M 【公式(1)】 5*T5=M5 > M 【公式(2)】 7*T7=M7 > M 【公式(3)】 从中令新的M = min(M3 , M5 , M7),并更新T3,T5,T7,使得新的T3,有3*T3 > M,同理T5,T7 【操作1】 如果不更新,带来的问题就是,会陷入死循环 比如刚开始M=1,初始T3=T5=T7=1,满足上述条件后,M=3,此时3*T3 <= M,则T3=1没有等于3,同理后续T5=1,T7=1,而M=7, 之后就发现T3,T5,T7中没有一个能符合上述公式(1),(2),(3),则M一直变成7不再变化; 为了防止这种情况,要进行上述操作1的处理,为的就是能够作为下一个丑数M的候选值能够一直变大 */ int min(int a , int b , int c) { int minNum = a < b ? a : b; minNum = minNum < c ? minNum : c; return minNum; } int findUglyNumber(int k) { int *pArray = new int[k + 1]; pArray[0] = 1; int* p3 , *p5 , *p7; p3 = p5 = p7 = pArray; int count = 0; int minNum; while(count < k) { count++; minNum = min( *p3 * 3 , *p5 * 5 , *p7 * 7); pArray[count] = minNum; //注意等号不能取,while中循环条件如果改成 *p3 * 3 < minNum 是错误的,这样会陷入死循环,使得minNum候选的几个候选值不再变化 while( *p3 * 3 <= minNum ) { p3++; } while( *p5 * 5 <= minNum) { p5++; } while( *p7 * 7 <= minNum) { p7++; } } int result = pArray[k]; delete[] pArray; return result; } void process() { int k; while(cin >> k) { int result = findUglyNumber(k); cout << result << endl; } } int main(int argc , char* argv[]) { process(); getchar(); return 0; }
相关文章推荐
- 有些数的素因子只有3,5,7.请设计一个算法,找出其中第k个数
- 有些数的素因子只有3,5,7.请设计一个算法,找出其中第k个数
- 9.7数学与概率(五)——功能:有些数的素数因子只有3、5、7,找出其中第k个数
- 程序员面试金典——解题总结: 9.18高难度题 18.11给定一个方阵,其中每个单元(像素)非黑即白。设计一个算法,找出四条边都是黑色像素的最大子方阵。
- 有一个排好序的数列,数列中只有一个数只出现1次,其余每个数均出现了两次,设计出一个算法,找出那个只出现了一次的数
- 程序员面试金典——解题总结: 9.17中等难题 17.12设计一个算法,找出数组中两数之和为指定值的所有整数对。
- 程序员面试金典: 9.4树与图 4.2给定有向图,设计一个算法,找出两个节点之间是否存在一条路径。
- 《程序员面试金典(第五版)》7.7:找出只含3/5/7因子的第K个数
- 程序员面试金典: 9.7数学与概率 7.6在二维平面上,有一些点,请找出经过点最多的那条线
- 程序员面试金典——解题总结: 9.18高难度题 18.6设计一个算法,给定10亿数字,找出最小的100万个数字。假定计算机内存足以容纳全部10亿个数字。
- 设计一个算法,找出只含素因子2,3,5 的第 n 小的数。
- 折半查找实现算法二(递归办法)PS:编译后有一个warning,但不影响结果,代码设计上应该还有些问题
- 一串首尾相连的珠子(m个),有N种颜色(N<=10),设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短
- Sumdiv 数论提 (数学很重要),这道题中算法变成了次要因素,数学才是最重要的,注意其中的一个经典公式(求因数和的)(很好推导)
- 一串首尾相连的珠子(m 个),有N 种颜色(N<=10),设计一个算法,取出其中一段,要求包含所有N 中颜色,并使长度最短。
- 13、设计一个算法,找出二叉树上任意两个结点的最近共同父结点。
- 给出101个整数数,这101个数是1~100中的数,其中只有一个是出现两次的数,要求找出这个数。
- (最优解)阿里笔试题请设计一个算法,在满足质因数仅为3,5,7或其组合的数中,找出第K大的数。比如K=1,2,3时,分别应返回3,5,7。要求算法时间复杂度最优。
- 一个整数数列,元素取值可能是1~N(N是一个较大的正整数)中的任意一个数,相同数值不会重复出现。设计一个算法,找出数列中符合条件的数对的个数,满足数对中两数的和等于N+1
- 一串首尾相连的珠子(m个),有N种颜色(N《=10),设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短。并分析时间复杂度与空间复杂度