263. Ugly Number
Problem Description
An ugly number is a positive integer whose prime factors are limited to 2, 3, and 5.
Given an integer n, return true if n is an ugly number.
Example 1:
Input: n = 6
Output: true
Explanation: 6 = 2 × 3
Example 2:
Input: n = 1
Output: true
Explanation: 1 has no prime factors, therefore all of its prime factors are limited to 2, 3, and 5.
Example 3:
Input: n = 14
Output: false
Explanation: 14 is not ugly since it includes the prime factor 7.
Constraints:
-2³¹ <= n <= 2³¹ - 1
Solution
Python Solution
class Solution:
def isUgly(self, n: int) -> bool:
# Handle non-positive numbers
if n <= 0:
return False
# Divide by 2, 3, and 5 as many times as possible
for prime in [2, 3, 5]:
while n % prime == 0:
n //= prime
# If n is 1, it means all prime factors were 2, 3, or 5
return n == 1
Time Complexity: O(log n)
The number of divisions is proportional to the number of prime factors.
Space Complexity: O(1)
Only uses a constant amount of extra space.
Java Solution
class Solution {
public boolean isUgly(int n) {
// Handle non-positive numbers
if (n <= 0) {
return false;
}
// Divide by 2, 3, and 5 as many times as possible
int[] primes = {2, 3, 5};
for (int prime : primes) {
while (n % prime == 0) {
n /= prime;
}
}
// If n is 1, it means all prime factors were 2, 3, or 5
return n == 1;
}
}
Time Complexity: O(log n)
The number of divisions is proportional to the number of prime factors.
Space Complexity: O(1)
Only uses a constant amount of extra space.
C++ Solution
class Solution {
public:
bool isUgly(int n) {
// Handle non-positive numbers
if (n <= 0) {
return false;
}
// Divide by 2, 3, and 5 as many times as possible
vector primes = {2, 3, 5};
for (int prime : primes) {
while (n % prime == 0) {
n /= prime;
}
}
// If n is 1, it means all prime factors were 2, 3, or 5
return n == 1;
}
};
Time Complexity: O(log n)
The number of divisions is proportional to the number of prime factors.
Space Complexity: O(1)
Only uses a constant amount of extra space.
JavaScript Solution
/**
* @param {number} n
* @return {boolean}
*/
var isUgly = function(n) {
// Handle non-positive numbers
if (n <= 0) {
return false;
}
// Divide by 2, 3, and 5 as many times as possible
const primes = [2, 3, 5];
for (const prime of primes) {
while (n % prime === 0) {
n /= prime;
}
}
// If n is 1, it means all prime factors were 2, 3, or 5
return n === 1;
};
Time Complexity: O(log n)
The number of divisions is proportional to the number of prime factors.
Space Complexity: O(1)
Only uses a constant amount of extra space.
C# Solution
public class Solution {
public bool IsUgly(int n) {
// Handle non-positive numbers
if (n <= 0) {
return false;
}
// Divide by 2, 3, and 5 as many times as possible
int[] primes = {2, 3, 5};
foreach (int prime in primes) {
while (n % prime == 0) {
n /= prime;
}
}
// If n is 1, it means all prime factors were 2, 3, or 5
return n == 1;
}
}
Time Complexity: O(log n)
The number of divisions is proportional to the number of prime factors.
Space Complexity: O(1)
Only uses a constant amount of extra space.
Approach Explanation
The solution uses prime factorization to determine if a number is ugly:
- Key Insight:
- Ugly numbers only have 2, 3, and 5 as prime factors
- Repeatedly divide by these primes until no longer possible
- If result is 1, the number is ugly
- Algorithm Steps:
- Handle non-positive numbers first
- Divide by each prime factor repeatedly
- Check if final result is 1
Example walkthrough for n = 12:
- Initial number: 12
- Divide by 2: 12 → 6 → 3
- Divide by 3: 3 → 1
- Result is 1, so 12 is ugly
Key insights:
- Order of division doesn't matter
- Negative numbers are never ugly
- 1 is considered ugly by definition
- Efficient prime factorization
Edge Cases:
- Negative numbers
- Zero
- One
- Large numbers with other prime factors