leetcode Ugly Number
Write a program to check whether a given number is an ugly number.
Ugly numbers are positive numbers whose prime factors only include
2, 3, 5
. For example,6, 8
are ugly while14
is not ugly since it includes another prime factor7
.Note that
1
is typically treated as an ugly number.
题目地址: leetcode Ugly Number
题意:
Ugly numbers 是一个只能被2,3,5整除的数,给你一个数,判断是否是 ugly number
思路:
直接分别除2,3,5。。。看看最后是不是1
注意0的情况
C++ 1
2
3
4
5
6
7
8
9class Solution {
public:
bool isUgly(int num) {
if(num == 0) return false;
for (int x : vector<int>{2,3,5})
while (num % x == 0) num /= x;
return num == 1;
}
};
Java 1
2
3
4
5
6
7
8class Solution {
public boolean isUgly(int num) {
if(num == 0) return false;
for (int x : new int[]{2, 3, 5})
while (num % x == 0) num /= x;
return num == 1;
}
}
Python 1
2
3
4
5
6
7
8
9
10
11class Solution(object):
def isUgly(self, num):
"""
:type num: int
:rtype: bool
"""
if not num: return False
for x in (2, 3, 5):
while num % x == 0:
num /= x
return num == 1;
264. Ugly Number II
Write a program to find the
n
-th ugly number.Ugly numbers are positive numbers whose prime factors only include
2, 3, 5
. For example,1, 2, 3, 4, 5, 6, 8, 9, 10, 12
is the sequence of the first10
ugly numbers.Note that
1
is typically treated as an ugly number.
题目地址: leetcode Ugly Number II
题意:
Ugly numbers 是一个只能被2,3,5整除的数,求第n个Ugly number
思路:
方法1
优先队列,每次取出当前的ugly number,然后乘上2,3,5
- *2:肯定是没放入队列中的
- *3:若一个数不是6的倍数,那么说明肯定没有加入队列中,可以加入
- *5:若不是10或者15的倍数,说明也没加入到队列中
复杂度:nlogn
1 | class Solution { |
方法2:
我们来看看,要如何求第n个ugly number.
第一个ugly number 是1 我们讨论n大于1的情况
因为它只能被2,3,5整除,所以我们从1开始扩展,每次要么乘2,要么乘3,要么乘5.
对于1来说,我们分别乘以2,3,5得到[2,3,5],显然2是最小的。
于是第2个ugly number是2。
接着第3个呢?显然是 3 . 从 1 * 3 得到
第4个就不一样了,它是从2*2得到。
这有什么规律呢?规律就是,每个因子分别乘以当前得到的ugly number(初始为1),当某因子x算出来的不大于其他两个因子,说明新的ugly number是当前因子算出来的,下一轮,该因子应该乘以之前ugly number的下一个。
换句话说,每个因子分别乘以对应的ugly number[i]后,如果得到了新的ugly number 就说明下一次应该乘以下一个(ugly number[i+1])。这样能保证乘出来的小而且不会漏掉。
另一种理解:一个丑数*2, *3, *5 就会得到另外的一个丑数,那么已知n个丑数,要得到n + 1个丑数的时候,必然是从前n个丑数*2, *3, *5 得到的。因此就变成了一个合并三个有序数组的问题:维护三个指针a, b, c,比较各自*2, *3, *5 得到的值最小(设为cur),则放入第 n + 1个位置。同时,为了不产生重复解,下面的代码用了if
而不是else if
来跳过重复解。
详见代码:
C++
1 | class Solution { |
Java
1 | class Solution { |
Python 1
2
3
4
5
6
7
8
9
10
11
12
13
14class Solution(object):
def nthUglyNumber(self, n):
"""
:type n: int
:rtype: int
"""
a = b = c = 0
ans = [1] * n
for i in range(1, n):
ans[i] = min(ans[a] * 2, ans[b] * 3, ans[c] * 5)
if ans[a] * 2 == ans[i]: a += 1
if ans[b] * 3 == ans[i]: b += 1
if ans[c] * 5 == ans[i]: c += 1
return ans[n - 1]
更多题解可以查看: https://www.hrwhisper.me/leetcode-algorithm-solution/