JAVA程序设计:第 N 个神奇数字(LeetCode:878)

如果正整数可以被 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

思路:我们知道答案一定不会超过A*N和B*N的最小值,因此我们可以二分答案,对于当前二分到的值,其能满足被A整除和被B整除的数的个数为A的倍数的个数+B的倍数的个数-A和B的最小公倍数的倍数的个数

class Solution {
	
	private int mod=1000000007;
	
    public int nthMagicalNumber(int N, int A, int B) {
    	
    	return Math.min(work(N,A,B), work(N,B,A));
    }
    
    private int work(int n,int a,int b) {
    	
    	long l=a,r=(long)a*n,res=-1;
    	while(l<=r) {
    		long mid=(l+r)/2;
    		if(mid/a+mid/b-mid/lcm(a,b)>=n) {
    			res=mid;
    			r=mid-1;
    		}
    		else
    			l=mid+1;
    	}
    	
    	return (int)(res%mod);
    	
    }
    
    private long lcm(int a,int b) {
    	
    	return (long)a*b/gcd(a,b);
    }
    
    private int gcd(int a,int b) {
    	if(b==0) return a;
    	return gcd(b,a%b);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值