leetcode.878 第N个神奇数字 - 数学 + gcd lcm + 二分

878. 第 N 个神奇数字

java版最大公约数gcd

public int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}

最小公倍数lcm

int lcm = a*b/gcd(a,b);

思路:

  • 令 f(x) 为所有小于等于x的神奇数字的数量    f(x)单调递增
  • 可以用二分查找第一个使 f(x)=n 的x值 即为答案

f(x)求法:

  • 在【0,x】有 x/a 个可以被a整除的数,有 x/b 个可以被b整除的数
  • 但是区间内存在既可以被a整除,也可以被b整除的数,它们被加了2次,需要减掉
  • 既可以被a整除也可以被b整除的数有 x/lcm(a,b) 个
  • 综上所述:f(x)= x/a + x/b - x/lcm
class Solution {
    static long MOD=(long)1e9+7;

    public int nthMagicalNumber(int n, int a, int b) 
    {
        int lcm=a/gcd(a,b)*b;

        long l=0,r=(long)Math.min(a,b)*n;
        while(l>1;
            long fx=mid/a+mid/b-mid/lcm;
            if(fx>=n) r=mid;
            else l=mid+1;
        }
        return (int)(l%MOD);
    }

    public int gcd(int a,int b)
    {
        return b==0?a:gcd(b,a%b);
    }
}

 

你可能感兴趣的:(leetcode每日一题,算法,gcd,lcm,二分,数学)