Description
Ugly number is a number that only have factors
2
,3
and5
.Design an algorithm to find the *n*th ugly number. The first 10 ugly numbers are
1, 2, 3, 4, 5, 6, 8, 9, 10, 12...
Note that
1
is typically treated as an ugly number.Have you met this question in a real interview? Yes
Example
If
n=9
, return10
.Challenge
O(n log n) or O(n) time.
题目模板
class Solution { public: /** * @param n: An integer * @return: the nth prime number as description. */ int nthUglyNumber(int n) { // write your code here } };
题目大意
丑数就是倍数是因子有2或3或5的数。给你一个数n,让你算出第n个丑数是什么。
大概思路
刚开始我想把所有丑数都算出来,然后给一个n直接返回一个结果,这样时间复杂度为O(1),但是看到给的n是int类型,所以就打消了这个念头。
然后想着能不能维护一个小一点的数组,里面的数不停的循环更新,每算出一个数就放到数组的下一个位置。这个数组的大小在于三个分别指向乘2,乘3,乘5的指针能够拉开多远。
最后试出来大小在310和325之间,没再向下试。
每次取乘2,乘3,乘5三个值中最小的值放入数组中,第index个数++。循环每次取最小的值放入,就能算出。
class Solution {
public:
/**
* @param n: An integer
* @return: the nth prime number as description.
*/
//返回三个数中最小的那一个
int min3(int a, int b, int c){
return min(a, min(b, c));
}
int nthUglyNumber(int n) {
// write your code here
int uglysum = 325; //指示要维护的数组大小
int ugly[uglysum]; //要维护的数组
int index = 1; //当前是第index个数
int index2 = 0, index3 = 0, index5 = 0; //下一个要乘2,3,5的数当前所在数组的位置
int index0 = 1; //数组中下一个数应该放放位置
int re = 1; //要返回的数
ugly[0] = 1; //初始化
while(index != n){
int val = min3(ugly[index2]*2, ugly[index3]*3, ugly[index5]*5);
if(val == (ugly[index2]*2)){
index2++;
index2 %= uglysum;
ugly[index0] = val;
}
if(val == (ugly[index3]*3)){
index3++;
index3 %= uglysum;
ugly[index0] = val;
}
if(val == (ugly[index5]*5)){
index5++;
index5 %= uglysum;
ugly[index0] = val;
}
re = val;
index0++;
index0 %= uglysum; //在维护的数组中循环放置
index++;
}
return re;
}
};
细节
在程序中用三个单if而不用else if的原因是计算出来的数可能有重复的,比如2乘3和3乘2,这样做避免重复元素重复放入数组中。
题目链接:https://www.lintcode.com/problem/ugly-number-ii/description