Reference: Problem I & Problem II
Difficulty: Easy
My Post: Summary of Ugly Number I & II (dp, priority-queue)
Problem
Write a program to check whether a given number is an ugly number.
Ugly numbers are positive numbers whose
prime factorsonly include2, 3, 5.
Note:
Non-prime factorsare allowed, e.g.8is an ugly number.1is typically treated as an ugly number.- Input is within the 32-bit signed integer range: $[−2^{31}, 2^{31} − 1]$.
 
Example:
1  | Input: -1, 0  | 
Analysis
The brute-force solution is to check all prime factors of num. By examining prime factors, determining if the factor is a prime is costly.
Recursion
The idea is that if a number num has factors 2, 3, 5 remove the effect of these factors by division. For example, 21 has a factor 3, so we can determine if it is an ugly number by indirectly checking if 21 / 3 is an ugly number.
If num is an ugly number, we will be at last examining num = 1.
1  | 30 / 2 = 15  | 
If not:
1  | 31 --> false (cannot be divided by 2, 3, 5)  | 
Here is the code:
1  | public boolean isUgly(int num) {  | 
Time: $O(\log{N})$ since the num / 2 can only occur in $\log{N}$ times at most.
Space: $O(\log{N})$
Iteration
1  | public static boolean isUgly(int num) {  | 
Time: $O(\log{N})$
Space: $O(1)$
Ugly Number II
Write a program to find the
n-thugly number.
Ugly numbers are positive numbers whose
prime factorsonly include2, 3, 5.
Note:
1is typically treated as an ugly number.ndoes not exceed 1690.
Example:
1  | Input: n = 10  | 
Brute-force
1  | int[] divisors = new int[] { 2, 3, 5 };  | 
Priority Queue
An ugly number must be multiplied by either 2, 3, 5 from a smaller ugly number. We can use a priority queue, but have to remove duplicates when polling elements from it.
Note:
- Use 
longsince we may put in very large elements in advance, sayval * 5, although they are not within the range ofn. (int) Long,(Integer) Longare illegal.
1  | public int nthUglyNumber(int n) {  | 
Time: $O(N\log{N})$
Space: $O(N)$
DP (clever)
Since 1 <= n <= 1690, we can pre-compute n ugly numbers and return the result in constant time.
1  | int BOUND = 1690;  | 
Time: $O(N)$
Space: $O(N)$