《程序员面试金典(第五版)》7.7:找出只含3/5/7因子的第K个数

从今天开始就开始完成《程序员面试经典》上面的题了,这本书是用java语言来实现的,本来也想着用java语言来实现而来使自己熟悉一下java方面的知识,但是后来想了想,发现向这样的算法题,还是直接用C语言来实现吧,若可以,我也会用java来实现。

今天是《程序员面试金典(第五版)》的第一个题目。
题目如下:

有些数的因子只有3、5 、7,请设计一个算法来寻找第k个数。
满足上面条件的数为:3 、5、 7、 9、 15、 21、 25等
输入为1 ,则输出为3
输入为2,则输出为5
输入为6,则输出21

实现代码如下:

/*有些数只含有357这三个因子中的一个或某几个,求出第K个数*/ 

/*
解题思路的找丑数的思路类似。
方法一:暴力搜索法:从1开始遍历,对每个数进行这样的判断:是否只有这三个因子。这种方法的时间复杂度为O(n),n为第k个数的大小。

方法二:用O(k)的辅助空间来得到O(k)的时间复杂度.
即下一个数一定是之前那些符合条件的数乘以3/5/7的最小的结果。 
*/



#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//在两个数中找出最小数 
int twoNumMin(int a,int b){
    return (a<=b)?a:b;
}
//在三个数中找出最小数 
int my_min(int a,int b,int c){
    return twoNumMin(twoNumMin(a,b),c);
}

int findNumofK(int k){
    if(k<=0){
        return -1;
    }
    //临时数组,来保存结果,这样就可以使得时间复杂度为O(k)
    int tempResult[k+1];

    memset(tempResult,0,(k+1)*sizeof(int)); 
    tempResult[0]=1;
    int curIndex=1;
    int *p3=tempResult;
    int *p5=tempResult;
    int *p7=tempResult;
    while(curIndex<k+1){
        int min=my_min((*p3)*3,(*p5)*5,(*p7)*7);
        tempResult[curIndex]=min;
        curIndex++;
        //下面3个循环始终保持 这三个指针所指向的数  乘以相应的数之后大于此时的最小值,然后为下一次选择最小值做准备。 
        while((*p3)*3<=min){
            p3++;
        }
        while((*p5)*5<=min){
            p5++;
        }
        while((*p7)*7<=min){
            p7++;
        }
    }
    return tempResult[k];

}

int main(void){
    int k;
    while(scanf("%d",&k)!=EOF&&k>0){

        int result=findNumofK(k);
        printf("%d\n",result);
    }

    return 0;
} 

你可能感兴趣的:(java,面试,C语言,丑数,程序员面试金典)