★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(let_us_code)
➤博主域名:https://www.zengqiang.org
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/11565804.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
Write a program to find the n
-th ugly number.
Ugly numbers are positive integers which are divisible by a
or b
or c
.
Example 1:
Input: n = 3, a = 2, b = 3, c = 5 Output: 4 Explanation: The ugly numbers are 2, 3, 4, 5, 6, 8, 9, 10... The 3rd is 4.
Example 2:
Input: n = 4, a = 2, b = 3, c = 4 Output: 6 Explanation: The ugly numbers are 2, 3, 4, 6, 8, 9, 12... The 4th is 6.
Example 3:
Input: n = 5, a = 2, b = 11, c = 13 Output: 10 Explanation: The ugly numbers are 2, 4, 6, 8, 10, 11, 12, 13... The 5th is 10.
Example 4:
Input: n = 1000000000, a = 2, b = 217983653, c = 336916467 Output: 1999999984
Constraints:
1 <= n, a, b, c <= 10^9
1 <= a * b * c <= 10^18
- It's guaranteed that the result will be in range
[1, 2 * 10^9]
请你帮忙设计一个程序,用来找出第 n
个丑数。
丑数是可以被 a
或 b
或 c
整除的 正整数。
示例 1:
输入:n = 3, a = 2, b = 3, c = 5 输出:4 解释:丑数序列为 2, 3, 4, 5, 6, 8, 9, 10... 其中第 3 个是 4。
示例 2:
输入:n = 4, a = 2, b = 3, c = 4 输出:6 解释:丑数序列为 2, 3, 4, 6, 8, 9, 12... 其中第 4 个是 6。
示例 3:
输入:n = 5, a = 2, b = 11, c = 13 输出:10 解释:丑数序列为 2, 4, 6, 8, 10, 11, 12, 13... 其中第 5 个是 10。
示例 4:
输入:n = 1000000000, a = 2, b = 217983653, c = 336916467 输出:1999999984
提示:
1 <= n, a, b, c <= 10^9
1 <= a * b * c <= 10^18
- 本题结果在
[1, 2 * 10^9]
的范围内
Runtime: 12 ms
Memory Usage: 20.7 MB
1 class Solution { 2 func nthUglyNumber(_ n: Int, _ a: Int, _ b: Int, _ c: Int) -> Int { 3 var low:Int = 0 4 var high:Int = Int.max 5 while (low < high) 6 { 7 let mid:Int = (low + high) / 2 8 if countUgly(mid, a, b, c) < n 9 { 10 low = mid + 1 11 } 12 else 13 { 14 high = mid 15 } 16 } 17 return low 18 } 19 20 //MARK:Stein算法 21 func gcd(_ a:Int,_ b:Int) -> Int 22 { 23 var a = a 24 var b = b 25 var acc:Int = 0 26 while((a & 1) == 0 && (b & 1) == 0) 27 { 28 acc += 1 29 a >>= 1 30 b >>= 1 31 } 32 while ((a & 1) == 0) {a >>= 1} 33 while ((b & 1) == 0) {b >>= 1} 34 if a < b {swap(&a,&b)} 35 while (a != 0) 36 { 37 while ((a & 1) == 0) 38 { 39 a >>= 1 40 } 41 if a < b{swap(&a,&b)} 42 a = (a - b) >> 1 43 } 44 return b << acc 45 } 46 47 func swap(_ x:inout Int,_ y:inout Int) 48 { 49 x = x ^ y 50 y = x ^ y 51 x = x ^ y 52 } 53 54 func lcm( _ x: Int, _ y: Int) -> Int 55 { 56 return x / gcd(x, y) * y 57 } 58 59 func countUgly(_ n: Int, _ a: Int, _ b: Int, _ c: Int) -> Int 60 { 61 var answer = n / a + n / b + n / c 62 answer -= n / lcm(a, b) + n / lcm(b, c) + n / lcm(c, a) 63 answer += n / lcm(lcm(a, b), c) 64 return answer 65 } 66 }
12ms
1 class Solution { 2 var a = 0 3 var b = 0 4 var c = 0 5 func nthUglyNumber(_ n: Int, _ a: Int, _ b: Int, _ c: Int) -> Int { 6 var left = 2 7 var right = Int.max 8 self.a = a 9 self.b = b 10 self.c = c 11 12 while left < right { 13 let mid = left + (right - left) / 2 14 15 if rank(mid) >= n { 16 right = mid 17 } else { 18 left = mid + 1 19 } 20 } 21 22 return left 23 } 24 25 fileprivate func rank(_ num: Int) -> Int { 26 27 var result = 0 28 result += num / a 29 result += num / b 30 result += num / c 31 32 result += num / lcm(c, lcm(a, b)) 33 result -= num / lcm(a, b) 34 result -= num / lcm(a, c) 35 result -= num / lcm(c, b) 36 return result 37 } 38 39 fileprivate func gcd(_ a:Int, _ b:Int) -> Int { 40 if a == 0 { return b } 41 return gcd(b % a, a) 42 } 43 44 fileprivate func lcm(_ a:Int, _ b:Int) -> Int { 45 return (a * b) / gcd(a, b) 46 } 47 }