思路
-
想写筛法,失败
-
见leetcode题解。
-
思路,只需要求1和3,5,7的任意(3, 5, 7)倍的数才是满足要求的。
两种方式,一种是维护一个最小堆,堆顶存放上面的满足要求的数,需要对数字去重
一个是维护三个指针:
(来自leetcode)
vector<int>nums(k+1); nums[0] = 1; int i3 = 0; int i5 = 0; int i7 = 0; // 遍历一共k-1次 for (int i = 1; i < k; ++i) { nums[i] = min(min(nums[i3] * 3, nums[i5] * 5), nums[i7] * 7); // 已经去重 if (nums[i] == nums[i3] * 3) { ++i3; } if (nums[i] == nums[i5] * 5) { ++i5; } if (nums[i] == nums[i7] * 7) { ++i7; } } return nums[k - 1];
代码
// class Solution {
// public:
// // practice
// vector<int>prime;
// vector<int>vis;
// // n是这个素数最大的范围
// void makePrime(int _n){
// vis.resize(_n+1);
// prime.clear();
// for(int i=2;i<=_n;i++){
// if(!vis[i]){
// prime.push_back(i);
// }
// for(int j=0;j<prime.size();j++){
// if(i*prime[j]>_n)break;
// vis[i*prime[j]]=true;
// if(i%prime[j]==0)break;
// }
// }
// }
// vector<int>vis1;
// void remove357(int _n){
// vis.resize(_n+1);
// vis1.resize(_n+1);
// prime.clear();
// for(int i=2;i<=_n;i++){
// if(!vis[i]){
// prime.push_back(i);
// }
// if(prime.size()<5){// 2,3,5,7,2的倍数需要筛除,除了3,5,7,其它素数的倍数也需要筛除
// if(i*prime[0]<=_n){
// vis1[i*prime[0]]=true;
// }
// for(int j=0;j<prime.size();j++){
// if(prime[j]*i>_n)break;
// vis[prime[j]*i]=true;
// if(i%prime[j]==0)break;
// }
// }
// else{
// // 2的倍数
// if(i*prime[0]<=_n){
// vis1[i*prime[0]]=true;
// }
// for(int j=0;j<4;j++){
// if(prime[j]*i>_n)break;
// vis[prime[j]*i]=true;
// if(i%prime[j]==0)break;
// }
// for(int j=4;j<prime.size();j++){
// if(i*prime[j]>_n)break;
// vis1[i*prime[j]]=true;
// vis[i*prime[j]]=true;
// // if(i%prime[j]==0)break;
// }
// }
// }
// }
// int getKthMagicNumber(int k) {
// if(k<=0){
// return 0;
// }
// // makePrime(100);
// int n=10000;
// remove357(n);
// vis[2]=vis1[2]=true;
// for(int i=1;i<=n;i++){
// if(!vis1[i]&&(vis[i]||i<=7)){
// cout<<i<<" ";
// }
// }
// cout<<endl;
// // 筛掉有3,5,7作为约数的数字
// int cnt=0;
// int i=0;
// for(i=1;cnt<k;i++){
// if(!vis1[i]&&(vis[i]||i<=7))// 素数或者只是3,5,7的倍数
// {
// cnt++;
// }
// }
// return i-1;
// }
// };
class Solution {
public:
// 维护一个小根堆,获得最小值
// int getKthMagicNumber(int k) {
// // 3,5,7的若干倍
// priority_queue<long long,vector<long long>,greater<long long> >q;
// q.push(1);
// long long top;
// for(int i=0;i<k;i++){// k次循环获取
// top=q.top();
// // 去除重复元素
// while(!q.empty()&&top==q.top()){
// q.pop();
// }
// q.push(3*top); // 可能会溢出
// q.push(5*top);
// q.push(7*top);
// }
// return top;
// }
int getKthMagicNumber(int k) {
vector<int>nums(k+1);
nums[0] = 1;
int i3 = 0;
int i5 = 0;
int i7 = 0;
// 遍历一共k-1次
for (int i = 1; i < k; ++i)
{
nums[i] = min(min(nums[i3] * 3, nums[i5] * 5), nums[i7] * 7);
// 已经去重
if (nums[i] == nums[i3] * 3)
{
++i3;
}
if (nums[i] == nums[i5] * 5)
{
++i5;
}
if (nums[i] == nums[i7] * 7)
{
++i7;
}
}
return nums[k - 1];
}
};