丑数
我们把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。
示例:
输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。
说明:
1 是丑数。
n 不超过1690。
这道题中的丑数是一个新的概念,如果在面试中听到一个新的概念要和面试官多沟通,多问。不能在概念不清的概念下就盲目的写代码。这道题更能反映出沟通能力。
解法:解法一使用暴力法,一个一个试,看哪个数是一个丑数将计数加一,但是有很多的多余计算。
解法二:用三个哨兵,后面的丑数是基于前面的丑数生成的,哪个哨兵计算出来一个数并被接收,哨兵的等级就被提升一个点,
Solution 1(暴力法)超时
class Solution {
public:
int nthUglyNumber(int n) {
if(n <= 0)
return -1;
int count = 0;
int i = 0;
while(count < n){
i++;
if(isUgly(i)){
count++;
}
}
return i;
}
bool isUgly(int n){
while(n%2 == 0)
n = n / 2;
while(n%3 == 0)
n = n / 3;
while(n%5 == 0)
n = n / 5;
return n == 1;
}
};
Solution 2(三指针法)
class Solution {
public:
int nthUglyNumber(int n) {
if(n <= 0)
return -1;
vector<int> result(n,0);
int id2,id3,id5;
id2 = id3 = id5 = 0;
result[0] = 1;
for(int i=1;i<n;i++){
result[i] = min(result[id2]*2,min(result[id3]*3,result[id5]*5)); // 每个哨兵计算一个,谁的小用谁的
if(result[i] == result[id2]*2) // 是哪个哨兵计算出来的就将哨兵的等级增加一位
id2++;
if(result[i] == result[id3]*3)
id3++;
if(result[i] == result[id5]*5)
id5++;
}
return result.back();
}
};
``