我突然发现我的草稿箱有43个,笑死我了...
题目描述:
题目链接:
题目分析:
也就是说要找到能被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;
}
}