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的最小值。妙啊。
我还没有写过二分,写二分很容易死循环。有空要钻研一下循环不变量。
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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。