1.二分
由于数组较大,使用二分法,logn
对于一个数,有多少个丑数小于等于该数是可以快速计算出来的
对于数n,小于n的丑数中包含因子a的个数为n/a,包含因子b的丑数为n/b,包含因子c的丑数为n/c
但是需要注意一些丑数的因子包含a b、b c、a c、a b c
故小于n的丑数个数为
n/a+n/b+n/c-n/ab-n/ac-n/bc+n/abc,
此处的ab表示a b的最小公倍数,ac bc abc同理
代码如下:
class Solution {
public:
long gcd(long a,long b)
{
return b==0?a:gcd(b,a%b);
}
//求a b的最小公倍数
long LCM(long a, long b) {
return a * b /gcd(a, b);
}
int nthUglyNumber(int n, int a, int b, int c) {
long ab = LCM(a, b);
long ac = LCM(a, c);
long bc = LCM(b, c);
long abc = LCM(ab, c);
long l = min(a, min(b, c));
long r = 2 * 10e9;
while (l < r) {
long m = l + (r - l) / 2;
long count = m / a + m / b + m / c - m / ab - m / ac - m / bc + m / abc;
if (count < n) {
l = m + 1;
} else {
r = m;
}
}
return l;
}
};