LeetCode 878. 第 N 个神奇数字

看用题目难度和用例规模就知道不能用暴力搜索

对于每个神奇数字,可以知道是一直在递增的。因此我们可以使用一种方法来确定某一个数是否是神奇数字,并确定它是第几个神奇数字。然后就可以使用二分法,当大于n的时候,减小右边界,小于时增大左边界。

如何确定是第几个神奇数字:对于一个数x来说其中可以被a整除的个数为x / a,可以被b整除的个数为x / b,可以为a和b同时整除的个数为x / c (c为a和b的最小公倍数)

可以确定一个数是第几个神奇数字后,我们就可以用二分法来寻找第N个神奇数字了。区间为左开右闭,left为0,right为a和b中最小值乘N。

class Solution {
public:
    int gcd(int a, int b)
    {
        return b == 0 ? a : gcd(b, a % b);
    }
    int nthMagicalNumber(int n, int a, int b) {
        long long MOD = 1e9 + 7;
        if(a < b)
            swap(a, b);
        long long left = 0, right = (long) b * n;
        int c = a * b / gcd(a, b);
        while(left < right)
        {
            long long m = left + (right - left) / 2;
            if(m / a + m / b - m / c >= n)
                right = m;
            else
                left = m + 1;
        }
        return right % MOD;
    }
};

你可能感兴趣的:(题,leetcode,算法,职场和发展)