每日一刷——1206——第n个神奇数字——GCD、LCM问题

我突然发现我的草稿箱有43个,笑死我了...

题目描述:

题目链接:

878. 第 N 个神奇数字 - 力扣(LeetCode)

题目分析:

也就是说要找到能被a和b同时整除的第n个数字  

而且由于答案可能很大,需要对10的九次方+7取模

这个好神奇?!2能被3整除吗??

噢噢噢!!不好意思,我一个分析题目的我都没看清楚题目。。。

是能被  a    b  整除的!!!

而且整除是不是相当于就是那个数是

a*1  a*2  a*3  a*4.........如果此时x为a*36 ,是不是就代表前面有35个能被a整除的!!!


(我滴妈呀,求最大公约数和最小公倍数只需要一行代码就搞定了,救命啊啊啊,还是得记,,,

简单的基础的要是都不会,都说感觉有点难想出来,那难题咋写啊,死去的高中记忆又来攻击我哈)


解题思路:

1.===>如果要我们求的是第一百个神奇的数字,那么我们首先考虑这第一百个神奇数字有大致的范围么,如果有了这个范围我们可以尝试用二分来求解问题

2.target是给定的n值,也就是第几个;x是要求的神奇的数字;f(x)就是神奇的数字与n的关系,也就是说目前有多少个数字了

3.沿用二分的思路来解题,如果是到达了target了,就返回

====》那么究竟这个神奇的数字有大致的范围么,又怎么能确定它到底是第几个,它前面又有多少个呢??

        我们可以这样想一想:

        如果要求第100个数字,然后给定a=2;b=3;那么如果a*100=200,我们想一想这个神奇数字是不是在1---200之间,因为如果只按a来算,是不是200恰好就是第100个数字,但是我们现在不止有2,还有3,甚至还有俩一起同时取到的,所以这个神奇数字只可能比200小,肯定不可能比200大,是吧,那么现在它的范围就确定了,那么我们只需要再考虑如何求它是第几个神奇数字

核心就是搞定这个f(x):

        1---x之间能被a或者b整除的都是神奇的数字,那么这些神奇数字究竟有多少个,咋算?

能被a整除的有多少个:x/a

能被b整除的有多少个:x/b

但是这里边有一些是重复的,因为有的又可以被a整除,还能被b整除,那么就是重复的,重复的减掉一次就可以了

        那究竟有多少个呢?

其实就是:x/a +x/b -x/(a和b的最小公倍数)  而求出最小公倍数需要先求出最大公约数

题解:

class Solution {
    public int nthMagicalNumber(int n, int a, int b) {
        long result =0;
        long minab=minaandb(a,b);  //最小公倍数
        long left=0;
        long right=(long) n*Math.min(a,b);
        
        while(left<=right){
            long mid =left+(right-left)/2;
            if(mid/a +mid/b -mid/(minab) >=n){
                result =mid;
                right =mid-1;    // 可是为啥这里的right和left这样改变
            }else{
                left=mid+1;           
            }
        }
        return (int) (result % 1000000007);
    }

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

    public static long minaandb(int a,int b){
        return (a/gcd(a,b))*b;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值