A positive integer is magical if it is divisible by either A or B.
Return the N-th magical number. Since the answer may be very large, return it modulo 10^9 + 7
.
Example 1:
Input: N = 1, A = 2, B = 3
Output: 2
Example 2:
Input: N = 4, A = 2, B = 3
Output: 6
Example 3:
Input: N = 5, A = 2, B = 4
Output: 10
Example 4:
Input: N = 3, A = 6, B = 4
Output: 8
Note:
1 <= N <= 10^9
2 <= A <= 40000
2 <= B <= 40000
题目理解:
定义魔法数,能够被A或者B整除的数被称为魔法数,返回从1开始的第N个魔法数
解题思路:
首先,我们来判断一个任意的数num包含的最后一个魔法数是第几个魔法数,也就是判断1~num之间有多少个能被A或者B整除的数,这个很简单判断,我们用LCM(A,B)表示A和B的最小公倍数,那么1~num中包含
num / A + num / B - num / LCM(A, B)
个能够被A或者B整除的数。知道了这一点之后,我们可以用二分法找到一个合适的num,它包含的最大一个魔法数是第N个魔法数,然后找出这个魔法数即可
代码如下:
class Solution {
int A, B, LCM;
public int nthMagicalNumber(int N, int A, int B) {
this.A = A;
this.B = B;
LCM = getLCM();
int m = Math.min(A, B);
long left = 0, right = (long)N * m;
while(left < right) {
long mid = left + (right - left) / 2;
int id = index(mid);
if(id == N) {
left = mid;
break;
}
else if(id > N) {
right = mid;
}
else {
left = mid + 1;
}
}
while(index(left) < N)
left += m;
while(index(left) > N)
left -= m;
while(left % A != 0 && left % B != 0)
left--;
return (int)(left % 1000000007);
}
public int index(long N) {
long res = N / A;
res -= N / LCM;
res += N /B;
return (int)res;
}
public int getLCM() {
int m = Math.max(A, B);
int n = Math.min(A, B);
while(m % n != 0) {
int temp = m % n;
m = n;
n = temp;
}
return A * B / n;
}
}