0
点赞
收藏
分享

微信扫一扫

[leetcode每日一题]11.22

​​878. 第 N 个神奇数字​​

一个正整数如果能被 ​​a​​ 或 ​​b​​ 整除,那么它是神奇的。

给定三个整数 ​​n​​ , ​​a​​ , ​​b​​ ,返回第 ​​n​​ 个神奇的数字。因为答案可能很大,所以返回答案 对 ​109 + 7​​ 取模 后的值。

示例 1:

输入:n = 1, a = 2, b = 3
输出:2

示例 2:

输入:n = 4, a = 2, b = 3
输出:6

提示:

  • ​1 <= n <= 109
  • ​2 <= a, b <= 4 * 104

Solution

这题不应该被称作困难,至少这比前两天的题简单。

我的做法是找规律,首先求出它们的lcm,那么每次增加lcm,就会有m=l//a + l//b - 1个能被整除的数字。那么可以直接跳到最大的小于n的m处,数字为lcm*m,之后再搜寻下(n-m)位被整除的数即可。

代码(Python)

class Solution:
def nthMagicalNumber(self, n: int, a: int, b: int) -> int:
l = lcm(a, b)
a, b = min(a,b), max(a, b)
MOD = 1000000007
res = 0
x = l//a + l//b - 1
res = (n//x*l)%MOD
cur1 = 0
cur2 = 0
for i in range(n%x+1):
if cur1 <= cur2:
cur1 += a
else:
cur2 += b
return (res + min(cur1, cur2)) % MOD

题解:可以二分,使用容斥原理。其中所求的值为f为n的时候x的最小值。妙啊。

我还没有写过二分,写二分很容易死循环。有空要钻研一下循环不变量。

[leetcode每日一题]11.22_容斥原理

class Solution:
def nthMagicalNumber(self, n: int, a: int, b: int) -> int:
MOD = 10 ** 9 + 7
l = min(a, b)
r = n * min(a, b)
c = lcm(a, b)
while l <= r:
mid = (l + r) // 2
cnt = mid // a + mid // b - mid // c
if cnt >= n:
r = mid - 1
else:
l = mid + 1
return (r + 1) % MOD

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/nth-magical-number/solution/di-n-ge-shen-qi-shu-zi-by-leetcode-solut-6vyy/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



举报

相关推荐

0 条评论