剑指Offer:面试题34 丑数

来源:互联网 发布:淘宝监控插件 编辑:程序博客网 时间:2024/05/21 09:46
/*丑数:我们把只包含因子2、3和5的数称为丑数,求按照从小到大的顺序的第1500个丑数。例如6,8都是丑数,但14不是丑数,因为它包含因此7.习惯上我们把1当做第一个丑数。分析:采用累除法,凡是能除得尽的都是丑数,模拟素数筛选法来做,对模拟的素数筛选法中,2,3,5书上的方法:创建数组保存已经找到的丑数,用空间换时间。创建一个数组,里面的数字时排好序的丑数,每一个丑数都是前面的丑数乘以2,3,5关键:如何确保里面的丑数是排好序的。假设数组中已有部分排好序的丑数,把最大的丑数记为M。分析如何生成下一个丑数。该丑数= 前面某个丑数*(2或3或5),首先把每个已有丑数*2,能得到若干个<=M的结果,而这些必定存在。我们需要第一个大于M的结果,希望丑数是按从小到大顺序生成。把得到的第一个乘以2后大于M的结果即为M2,同样乘以3或5,得到M3,M5.下一个丑数 = min{M2,M3,M5}对于乘以2而言,存在丑数T2,排在它之前的每个丑数乘以2得到的结果<已有最大丑数,在它之后的每个丑数*2会太大。我们只需记录这个丑数的位置,同时每次生成新的丑数是,更新T2,对乘3和乘5而言,同样存在T3和T5。输入:输入包括一个整数N(1<=N<=1500)。输出:可能有多组测试数据,对于每组数据,输出第N个丑数。样例输入:3样例输出:3*//*关键:1 对于乘以2而言,存在丑数T2,排在它之前的每个丑数乘以2得到的结果<已有最大丑数,在它之后的每个丑数*2会太大。我们只需记录这个丑数的位置,同时每次生成新的丑数是,更新T2,对乘3和乘5而言,同样存在T3和T5。2  pMul2 = pMul3 = pMul5 = iUglyNumArr;//初始设定丑数数组中乘以2或3或5后,大于丑数数组中最大值的丑数指针为起始值3  int iMin = min(*pMul2*2,*pMul3*3,*pMul5*5);//选定丑数  iUglyNumArr[iNextIndex] = iMin;//设定下一个丑数  while(*pMul2*2 <= iMin)//更新丑数数组*(2或3或5)大于当前丑数数组中最大值的丑数的位置  {   pMul2++;  }*/#include <stdio.h>const int MAXSIZE = 1501;int min(int num1,int num2,int num3){ int iMin = num1 < num2 ? num1 : num2; iMin = iMin < num3 ? iMin : num3; return iMin;}int getUglyNum(int n){ if(n < 0 || n > 1500) {  return -1; } int iUglyNumArr[MAXSIZE]; iUglyNumArr[0] = 1; int iNextIndex = 1; int* pMul2,*pMul3,*pMul5; pMul2 = pMul3 = pMul5 = iUglyNumArr;//初始设定丑数数组中乘以2或3或5后,大于丑数数组中最大值的丑数指针为起始值 while(iNextIndex < n) {  int iMin = min(*pMul2*2,*pMul3*3,*pMul5*5);//选定丑数  iUglyNumArr[iNextIndex] = iMin;//设定下一个丑数  while(*pMul2*2 <= iMin)//更新丑数数组*(2或3或5)大于当前丑数数组中最大值的丑数的位置  {   pMul2++;  }  while(*pMul3*3 <= iMin)  {   pMul3++;  }  while(*pMul5*5 <= iMin)  {   pMul5++;  }  iNextIndex++; } return iUglyNumArr[n -1];}void process(){ int n; while(EOF != scanf("%d",&n)) {  if(n < 0 || n > 1500)  {   continue;  }  printf("%d\n",getUglyNum(n)); }}int main(int argc,char* argv[]){ process(); getchar(); return 0;}


 

0 0