• 笔试算法题(20):寻找丑数 & 打印1到N位的所有的数


    出题:将只包含2,3,5的因子的数称为丑数(Ugly Number),要求找到前面1500个丑数;

    分析:

    • 解法1:依次判断从1开始的每一个整数,2,3,5是因子则整数必须可以被他们其中的一个整除,如果不包含任何其他因子则最终的结果为1;
    • 解法2:小丑数必然是某个大丑数的因子,也就是乘以2,3,或者5之后的值,所以可以利用已经找到的丑数来寻找下一个丑数,使用数组有序保存已经找到的丑 数,并且当前最大丑数值为M;用大于M/2的丑数乘以2得到M1,用大于M/3的丑数乘以3得到M2,用大于M/5的丑数乘以5得到M3,最后M1,M2 和M3中最小的数就是下一个丑数;
    • 此题让人联想到素数的求解,素数解法中是从小到大将等于小数倍数的数去除,最后剩下的就是素数;而本题是需要找到这些从小到大等于小数倍数的数,因为仅需2,3,5作为因子才能满足要求;

    解题:

     1 bool IsUglyNumber(int n) {
     2         while(n%2 == 0)
     3                 n/=2;
     4         while(n%3 == 0)
     5                 n/=3;
     6         while(n%5 == 0)
     7                 n/=5;
     8 
     9         if(n == 1)
    10                 return true;
    11         else
    12                 return false;
    13 }
    14 void BetterVersion(int limit) {
    15         /**
    16          * 创建数组array有序存储找到丑数
    17          * */
    18         int array[limit]; int length=2;
    19         array[0]=1;array[1]=2;array[2]=3;
    20         int M1, M2, M3,M;
    21 
    22         for(int j=0;j<limit-3;j++) {
    23                 /**
    24                  * 寻找大于已找到最大丑数,并且以小丑数和2,3或5
    25                  * 为因子的丑数
    26                  * */
    27                 for(int i=0;i<length;i++) {
    28                         if(array[i]*2>array[length]) {
    29                                 M1=array[i]*2;break;
    30                         }
    31                 }
    32                 for(int i=0;i<length;i++) {
    33                         if(array[i]*3>array[length]) {
    34                                 M2=array[i]*3;break;
    35                         }
    36                 }
    37                 for(int i=0;i<length;i++) {
    38                         if(array[i]*5>array[length]) {
    39                                 M3=array[i]*5;break;
    40                         }
    41                 }
    42                 /**
    43                  * 使用最小值作为下一个丑数
    44                  * */
    45                 M=M1;
    46                 if(M>M2) M=M2;
    47                 if(M>M3) M=M3;
    48                 array[++length]=M;
    49                 printf("
    %d",M);
    50         }
    51 }

    出题:输入数字N,N表示十进制数的位数,要求按序从1开始输出最大到N位的十进制数;

    分析:

    • 解法1:N位数可能超出任何机器的最大数字范围;所以需要使用string,array或者创建一个大数类型来表示数字,然后模拟每次加1的运算,注意最后数字溢出N位数字的判断;
    • 解法2:同样使用string或者array表示数字,不同的是使用递归全排列N位数字,每位数字可能的取值是0-9,但是当N较大时系统栈也可能溢出;

    解题:

     1 void printBigInt(int *array, int length, int index) {
     2         if(index == length) {
     3                 printf("
    ");
     4                 for(int i=0;i<length;i++) {
     5                         if(array[i] !=0) {
     6                                 for(int j=i;j<length;j++)
     7                                         printf("%d",array[j]);
     8                                 break;
     9                         }
    10                 }
    11                 return;
    12         }
    13         for(int i=0;i<=9;i++) {
    14                 array[index]=i;
    15                 printBigInt(array,length,index+1);
    16         }
    17 }
    18 void printBigInt(int length) {
    19         int array[length];
    20         for(int i=0;i<length;i++)
    21                 array[i]=0;
    22         printBigInt(array, length, 0);
    23 }
  • 相关阅读:
    Linux更新时,出现无法更新锁
    Linux显示su:认证失败
    08 redis的缓存预热,雪崩,击穿,穿透问题以及常用的监控参数
    06 redis的哨兵系统的工作流程
    05 redis的主从复制机制的工作流程以及相关基础知识
    03 redis的事务以及锁、过期数据的删除策略、逐出算法、配置文件的核心配置参数
    02 jedis以及redis的持久化
    01 redis的5种基本数据类型的介绍,使用以及应用场景
    M1 MySQL事务知识点的总结
    02 Java文件读写通道的使用以及文件的基本操作方法
  • 原文地址:https://www.cnblogs.com/leo-chen-2014/p/3744957.html
Copyright © 2020-2023  润新知