题目概述
设计一个算法,找出只含素因子2,3,5 的第 n 小的数。符合条件的数如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12…换句话说,就是我们要求出因数只是质数且可由2,3,5相乘得出,使用个数不限制,从一开始计算,要求完成函数返回第n个丑数,例如第九个就是10。
解题思路
思路一:采用暴力破解的方式:无限循环里面包含三个条件为模运算的循环来解出,当完成三个循环后结果为1即该数为丑数的做法来解答即可。但是这种方法当数量过大时不适合。
思路二:当排除1后,我们可以使用2,3,5来生成丑数,即丑数乘以2、3或5的结果也是丑数,每次可以生成三个。我们通过选取最小的来存储,为了生成的更加准确,我们通过数组下标移动的方式切且只移动符合要求的那个,采用vector存储更方便,集体思路看代码注释理解。
代码实现
#include <iostream>
#include <vector>
using namespace std;
/**
* 求符合要求的丑数
* @param n
* @return
*/
int nthUglyNumber(int n) {
//如果是1,直接返回
if (n == 1){
return 1;
}
//创建vector的int存储数据
vector<int> result;
//将特殊情况先存储进去
result.push_back(1);
//声明三个移动下标
int a, b, c;
a = b = c = 0;
//记录生成的数的个数
int index = 1;
while (index < n){
//将三个数进行比较:将最小的存储起来
result.push_back(min(2 * result[a], min(3 * result[b], 5 * result[c])));
//测试输出样例
cout << 2 * result[a] << " " << 3 * result[b] << " " << 5 * result[c] << endl;
//判断放入的是那中生成发式,然后将指标后移,用作下一次的生成
if (2 * result[a] == *(result.end() - 1)){
a++;
}
if (3 * result[b] == *(result.end() - 1)){
b++;
}
if (5 * result[c] == *(result.end() - 1)){
c++;
}
index++;
}
//vecter.end():返回元素指向最后一个元素的下一个位置
//因此,此处的(result.end()-1)返回的是result的最后一个元素的地址
return *(result.end()-1);
}
int main() {
int count = nthUglyNumber(5);
cout << count << endl;
return 0;
}
个人纪录
-
vecter的使用:
pop_back():追加到末尾
end():返回最后一个元素后一个位置的地址 -
min() max():可以直接使用比较
-
注意指针变量的使用