思路
題目要求第 個神奇數字,神奇數字滿足條件「被 整除或 整除」。 假設 , , ,神奇數字的順序是 ,那麼可能出現的答案,會落在哪個區間呢?
- 當中至少存在 個神奇數字: ,也就是 。
- 當中至少存在 個神奇數字: ,也就是 。 因此可能的答案範圍落在 。 後續計算需要扣掉重複計算的部分,也就是兩者的公倍數: ,也就是 。
現在找到兩邊界 ,接下來要透過二分找到答案。
- 中間點 ,那麼 之間有多少個神奇的數字?
- 倍數的神奇數字 + 倍數的神奇數字 - 倍數的神奇數字。
- (無條件捨去)
- ,更新邊界 ,
- ,得到第 個神奇數字是 。
程式碼
二分搜尋 + 容斥原理
class Solution {
private:
int mygcd(int a, int b) {
return b == 0 ? a : mygcd(b, a % b);
}
int mylcm(int a, int b) {
return a * b / mygcd(a, b);
}
public:
int nthMagicalNumber(int n, int a, int b) {
const int MOD = 1e9+7;
int lcm = mylcm(a, b);
long long left = 0, right = min(1LL * n * a, 1LL * n * b);
long long res = 0;
while(left <= right) { // 二分
long long mid = left + (right - left) / 2;
long long cnt = mid / a + mid / b - mid / lcm;
if(cnt >= n) {
res = mid;
right = mid - 1;
}
else {
left = mid + 1;
}
}
return res % MOD;
}
};
複雜度分析
- 時間複雜度:
- 空間複雜度: