A positive integer is magical if it is divisible by either a
or b
.
Given the three integers n
, a
, and b
, return the nth
magical number. Since the answer may be very large, return it modulo 109 + 7
.
Example 1:
Input: n = 1, a = 2, b = 3 Output: 2
Example 2:
Input: n = 4, a = 2, b = 3 Output: 6
Constraints:
1 <= n <= 109
2 <= a, b <= 4 * 104
This problem asks to find the nth number that is divisible by either a
or b
. A straightforward approach would be to iteratively generate numbers and check divisibility, but this is inefficient for large n
. A more efficient solution utilizes binary search and the inclusion-exclusion principle.
Core Idea:
The number of magical numbers less than or equal to x
can be calculated using the inclusion-exclusion principle:
count(x) = floor(x/a) + floor(x/b) - floor(x/lcm(a,b))
floor(x/a)
: counts numbers divisible by a
.floor(x/b)
: counts numbers divisible by b
.floor(x/lcm(a,b))
: corrects for double-counting numbers divisible by both a
and b
(i.e., divisible by their least common multiple).We want to find the smallest x
such that count(x) = n
. This is done efficiently using binary search.
Algorithm:
Find LCM: Calculate the least common multiple (lcm
) of a
and b
. The gcd
(greatest common divisor) function is used as a helper to compute the LCM efficiently using the formula: lcm(a, b) = (a * b) / gcd(a, b)
.
Binary Search: Perform a binary search within a suitable range. The upper bound of the search range can be estimated as (a + b) * n
, as it is unlikely for the nth magical number to exceed this. The lower bound is 0.
Count Magical Numbers: In each iteration of the binary search, calculate count(mid)
using the inclusion-exclusion formula, where mid
is the midpoint of the current search range.
Adjust Search Range: If count(mid)
is greater than or equal to n
, it means the nth magical number is less than or equal to mid
, so we narrow down the search range to the lower half. Otherwise, we search in the upper half.
Return Result: The binary search converges to the smallest x
such that count(x) >= n
, which is the nth magical number. We then return this value modulo 10^9 + 7
.
Time Complexity Analysis:
gcd
function: O(log(min(a, b))) due to the recursive nature.count
calculation: O(1) for each iteration.Therefore, the overall time complexity is dominated by the binary search, resulting in O(log((a+b)*n)).
Space Complexity Analysis:
The space complexity is O(1) as we only use a constant number of variables to store intermediate values.
Code Explanation (Python):
import math
def gcd(a, b):
while b:
a, b = b, a % b
return a
def lcm(a, b):
return a * b // gcd(a, b)
class Solution:
def nthMagicalNumber(self, n: int, a: int, b: int) -> int:
mod = 10**9 + 7
l, r = 0, (a+b)*n # Search range
c = lcm(a,b)
while l<=r:
mid = (l+r)//2
count = mid//a + mid//b - mid//c
if count >=n:
r = mid -1
else:
l = mid + 1
return (l)%mod
The other languages (Java, C++, Go) follow the same logic but have different syntax. The key components remain consistent: the gcd
, lcm
, binary search, and the inclusion-exclusion principle for counting magical numbers.