# 1201. Ugly Number III #### Difficulty: Medium link: https://leetcode.com/problems/ugly-number-iii/ ### 1. Binary Search #### $O(log\ (min(a, b, c) * n))$ runtime, $O(1)$ space 題目敘述説要找第kth個xxx,可以轉變思路,每次猜一個數字,檢查這個數字前面是不是有n個ugly number,找到滿足條件的最小值就是第kth個ugly number。 比較快的猜數字算法就是binary search,同樣套用模板。 計算前面有幾個ugly number是本題最需要靈感的地方,直接除a, b, c累加在一起就行,然而最大公倍數會重複計算,所以需要扣掉或補回來。 最大公倍數使用math套件的lcm。 邊界最大值設為min(a, b, c)的n倍,保證至少有n個ugly number;邊界最小值從以下兩者選擇較大的數,min(a, b, c)是第一個ugly number,而第n個ugly number一定比n大。 ##### python ```python= class Solution: def nthUglyNumber(self, n: int, a: int, b: int, c: int) -> int: ab = math.lcm(a, b) bc = math.lcm(b, c) ac = math.lcm(a, c) abc = math.lcm(a, b, c) def ugly_numbers_below_k(k): return k // a + k // b + k // c - k // ab - k // bc - k // ac + k // abc left, right = max(n, min(a, b, c)), min(a, b, c) * n while left < right: mid = left + (right - left) // 2 if ugly_numbers_below_k(mid) >= n: right = mid else: left = mid + 1 return left ``` ###### tags: `leetcode`