Skip to the content.

leetcode [878] 第 N 个神奇数字


Contact me:

Blog -> https://cugtyt.github.io/blog/index
Email -> cugtyt@qq.com
GitHub -> Cugtyt@GitHub


如果正整数可以被 A 或 B 整除,那么它是神奇的。

返回第 N 个神奇数字。由于答案可能非常大,返回它模 10^9 + 7 的结果。

示例 1:

输入:N = 1, A = 2, B = 3
输出:2

示例 2:

输入:N = 4, A = 2, B = 3
输出:6

示例 3:

输入:N = 5, A = 2, B = 4
输出:10

示例 4:

输入:N = 3, A = 6, B = 4
输出:8

提示:

1 <= N <= 10^9
2 <= A <= 40000
2 <= B <= 40000

来自题解

用数学方法找出第 NNN 个神奇数字。

神奇数字是有规律。设 L 为 A,B 的最小公倍数,如果 X ≤ L 是神奇数字,那么 X+L 也是神奇数字。

有 M = L / A + L / B − 1个神奇数字小于等于 L: 其中 L / A​ 个是能被 A 整除的,L / B 个能被 B 整除,1 个能同时被 A,B整除。

设 N = M ∗ q + r (r < M),前 L ∗ q 个数字有 M ∗ q 个神奇数字,(L ∗ q + 1, L ∗ q + 2, …) 之间有 r 个神奇数字。可以暴力搜 r,下一个神奇数字要么是 L ∗ q + A 要么是 L ∗ q + B,依此类推。

class Solution:
    def nthMagicalNumber(self, N: int, A: int, B: int) -> int:
        from fractions import gcd
        MOD = 10**9 + 7

        L = A // gcd(A, B) * B
        M = L // A + L // B - 1
        q, r = divmod(N, M)

        if r == 0:
            return q * L % MOD

        heads = [A, B]
        for _ in range(r - 1):
            if heads[0] <= heads[1]:
                heads[0] += A
            else:
                heads[1] += B

        return (q * L + min(heads)) % MOD