一文秒杀所有丑数系列问题
原创约 6183 字
本文讲解的例题
LeetCode | 力扣 | 难度 |
---|---|---|
313. Super Ugly Number | 313. 超级丑数 | 🟠 |
264. Ugly Number II | 264. 丑数 II | 🟠 |
263. Ugly Number | 263. 丑数 | 🟢 |
1201. Ugly Number III | 1201. 丑数 III | 🟠 |
最近读者群里有个读者跟我私信,说去面试微软遇到了一系列和数学相关的算法题,直接懵圈了。我看了下题目发现这些题其实就是 LeetCode 上面「丑数」系列问题的修改版。
首先,「丑数」系列问题属于会者不难难者不会的类型,因为会用到些数学定理嘛,如果没有专门学过,靠自己恐怕是想不出来的。
另外,这类问题而且非常考察抽象联想能力,因为它不仅仅要用到数学定理,还需要你把题目抽象成链表相关的题目运用双指针技巧,或者抽象成数组相关的题目运用二分搜索技巧。
那么今天我就来用一篇文章把所有丑数相关的问题一网打尽,看看这类问题能够如何变化,应该如何解决。
丑数 I
首先是力扣第 263 题「丑数」,题目给你输入一个数字 n
,请你判断 n
是否为「丑数」。所谓「丑数」,就是只包含质因数 2
、3
和 5
的正整数。
函数签名如下:
boolean isUgly(int n)
比如 12 = 2 x 2 x 3 就是一个丑数,而 42 = 2 x 3 x 7 就不是一个丑数。
这道题其实非常简单,前提是你知道算术基本定理(正整数唯一分解定理):
任意一个大于 1 的自然数,要么它本身就是质数,要么它可以分解为若干质数的乘积。
既然任意一个大于一的正整数都可以分解成若干质数的乘积,那么丑数也可以被分解成若干质数的乘积,且这些质数只能是 2, 3 或 5。
有了这个思路,就可以实现 isUgly
函数了:
java 🟢
class Solution {
public boolean isUgly(int n) {
if (n <= 0) return false;
// 如果 n 是丑数,分解因子应该只有 2, 3, 5
while (n % 2 == 0) n /= 2;
while (n % 3 == 0) n /= 3;
while (n % 5 == 0) n /= 5;
// 如果能够成功分解,说明是丑数
return n == 1;
}
}
cpp 🤖
class Solution {
public:
bool isUgly(int n) {
if (n <= 0) return false;
// 如果 n 是丑数,分解因子应该只有 2, 3, 5
while (n % 2 == 0) n /= 2;
while (n % 3 == 0) n /= 3;
while (n % 5 == 0) n /= 5;
// 如果能够成功分解,说明是丑数
return n == 1;
}
};
python 🤖
class Solution:
def isUgly(self, n: int) -> bool:
if n <= 0:
return False
# 如果 n 是丑数,分解因子应该只有 2, 3, 5
while n % 2 == 0:
n //= 2
while n % 3 == 0:
n //= 3
while n % 5 == 0:
n //= 5
# 如果能够成功分解,说明是丑数
return n == 1
go 🤖
func isUgly(n int) bool {
if n <= 0 {
return false
}
// 如果 n 是丑数,分解因子应该只有 2, 3, 5
for n % 2 == 0 {
n /= 2
}
for n % 3 == 0 {
n /= 3
}
for n % 5 == 0 {
n /= 5
}
// 如果能够成功分解,说明是丑数
return n == 1
}
javascript 🤖
var isUgly = function(n) {
if (n <= 0) return false;
// 如果 n 是丑数,分解因子应该只有 2, 3, 5
while (n % 2 == 0) n /= 2;
while (n % 3 == 0) n /= 3;
while (n % 5 == 0) n /= 5;
// 如果能够成功分解,说明是丑数
return n == 1;
};
丑数 II
接下来提升难度,看下力扣第 264 题「丑数 II」,现在题目不是让你判断一个数是不是丑数,而是给你输入一个 n
,让你计算第 n
个丑数是多少,函数签名如下:
java 🟢
int nthUglyNumber(int n)
cpp 🤖
int nthUglyNumber(int n)
python 🤖
def nthUglyNumber(n: int) -> int:
go 🤖
func nthUglyNumber(n int) int {}
javascript 🤖
var nthUglyNumber = function(n) {}