问题:
编写一个程序,找出第 n
个丑数。
丑数就是只包含质因数 2, 3, 5
的正整数。
示例:
输入:n = 10,输出:12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12,是前 10 个丑数。
说明:
1. 1
是丑数。
2. n
不超过1690。
思路与代码:
#include<stdio.h>
#include<stdlib.h>
int nthUglyNumber(int n);
void main(void) {
int n;
int result;
printf("请输入n的值:\n");
scanf_s("%d", &n);
result = nthUglyNumber(n);
printf("%d", result);
system("pause");
}
//求最小当前要插入的最小丑数
int MIN_ChouShu(int *p1, int *p2, int *p3) {
int min;
min = (*p1 < *p2) ? *p1 : *p2;
min = (*p3 < min) ? *p3 : min;
return min;
}
//后面的每个丑数都是前面的丑数乘以2/3/5得来的,因此每次计算前面丑数与2/3/5的乘积,并将最小的结果插入到丑数序列里。(效率高跟多)
int nthUglyNumber(int n) {
int ugly[1700] = { 1 };
int *p1 = (int *)malloc(sizeof(int));
int *p2 = (int *)malloc(sizeof(int));
int *p3 = (int *)malloc(sizeof(int));
int k;
int index2 = 0;
int index3 = 0;
int index5 = 0;
for (k = 0; k < n-1; k++) {
int val;
*p1 = ugly[index2] * 2;
*p2 = ugly[index3] * 3;
*p3 = ugly[index5] * 5;
val = MIN_ChouShu(p1, p2, p3);
if (val == ugly[index2] * 2)
index2++;
if (val == ugly[index3] * 3)
index3++;
if (val == ugly[index5] * 5)
index5++;
ugly[k + 1] = val;
}
return ugly[k];
}
从1开始遍历(超出时间限制),直到count=n,条件是:只要能整除2(3/5),就一直除以2(3/5),直到不能再继续除为止,如果最终结果为1,那么为丑数,否则不是丑数。
//int nthUglyNumber(int n) {
// int k;
// int tmp;
// int count = 0;
// for (k = 1; count < n; k++) {
// tmp = k;
// while (tmp % 2 == 0) {
// tmp /= 2;
// }
// while (tmp % 3 == 0) {
// tmp /= 3;
// }
// while (tmp % 5 == 0) {
// tmp /= 5;
// }
// if (tmp == 1)
// count++;
// }
// return --k; //这里是--k,因为最后一次循环k又加了1,所以输出要减1。
//}