版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/majichen95/article/details/82049503
设计一个算法,找出只含素因子2
,3
,5
的第 n 小的数。
符合条件的数如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12...
样例
如果n = 9
, 返回 10
挑战
要求时间复杂度为O(nlogn)或者O(n)
注意事项
我们可以认为1
也是一个丑数
解题思路:
暴力解法不做介绍大家都可以想到,在该题会time limited。换一种思路是:所有的肯定都是由2,3,5这三个数组成(1不算),则可以理解为后面的数由前面的数与2,3,5组合而成的。
如果 Ugly Number: 1, 2, 3, 4, 5, 6, 8, 10, ..........
那么 1*2 2*2 3*2 4*2 5*2 6*2 8*2 10*2 ...........*2
1*3 2*3 3*3 4*3 5*3 6*3 8*3 10*3 .......... *3
1*5 2*5 3*5 4*5 5*5 6*5 8*5 10*5 .......... *5
都是Ugly Number。产生下一个Ugly Number的方法则是选出ugly[num2]*2 , ugly[num3]*3 , ugly[num5]*5中最小的一个,得到丑数后,在相应的丑数因子计数器上+1 以便于寻找下一个更大的丑数。
只要不断把新产生的ugly number添加到ugly number数组中就可以了,直到找到第N个。
public class Solution {
/**
* @param n: An integer
* @return: the nth prime number as description.
*/
public int nthUglyNumber(int n) {
// write your code here
int[] ugly = new int[n];
ugly[0] = 1;
//定义因子计数器
int num2 = 0;
int num3 = 0;
int num5 = 0;
for(int i=1 ; i<n ; i++){
//新丑数是2,3,5倍数中最小
ugly[i] = getMin(ugly[num2]*2 , ugly[num3]*3 , ugly[num5]*5);
//判断新存放的丑数是2,3,5中的哪个数的倍数
//并在相应的倍数计数器+1,使得与因子相乘的数值变化,得到新的丑数
if(ugly[i] == ugly[num2]*2)
num2++;
if(ugly[i] == ugly[num3]*3)
num3++;
if(ugly[i] == ugly[num5]*5)
num5++;
}
return ugly[n-1];
}
public static int getMin(int num1 , int num2 , int num3){
int temp = num1 < num2 ? num1 : num2;
return temp < num3 ? temp : num3;
}
}