LeetCode 1201. Ugly Number III 数学+二分答案
An ugly number is a positive integer that is divisible by \(a\), \(b\), or \(c\).
Given four integers \(n\), \(a\), \(b\), and \(c\), return the \(n\)th ugly number.
Solution
考虑如何二分答案,假设一个函数 \(f(num,a,b,c)\) 会得到 \([1,num]\) 中 ugly number的个数,所以就是搜索左侧边界的二分
那么个数该如何求解呢?\([1,num]\) 中能被 \(a\) 整除的数个数为 \(num/a\), 同时被 \(a,b\) 整除的个数为 \(num/lcm(a,b)\),那么根据容斥即可
点击查看代码
class Solution:
def nthUglyNumber(self, n: int, a: int, b: int, c: int) -> int:
def gcd(a, b):
if a<b:
return gcd(b,a)
if b==0:
return a
return gcd(b, a%b)
def lcm(a, b):
return a*b/gcd(a,b)
def check(cand, a, b, c):
setA, setB, setC = int(cand/a), int(cand/b), int(cand/c)
setAB, setAC, setBC = int(cand/lcm(a,b)), int(cand/lcm(a,c)), int(cand/lcm(b,c))
setABC = int(cand/lcm(lcm(a,b),c))
return setA+setB+setC-setAB-setAC-setBC+setABC
left = 1
right = int(2e9)+1
while left<=right:
mid = left+int((right-left)/2)
if check(mid, a, b , c) < n:
left=mid+1
else:
right=mid-1
return left