An ugly number is a positive integer which does not have a prime factor other than 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.
Example 3:
Input: n = 14 Output: false Explanation: 14 is not ugly since it includes the prime factor 7.
Constraints:
-231 <= n <= 231 - 1When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach for the ugly number problem is about systematically checking numbers one by one. We start with the smallest number and keep checking if it's an ugly number until we've found enough ugly numbers.
Here's how the algorithm would work step-by-step:
def find_ugly_number_brute_force(number_index):
ugly_numbers_found = 0
current_number = 1
while ugly_numbers_found < number_index:
temp_number = current_number
# Repeatedly divide by 2, 3, and 5
while temp_number % 2 == 0:
temp_number //= 2
while temp_number % 3 == 0:
temp_number //= 3
while temp_number % 5 == 0:
temp_number //= 5
# An ugly number will simplify to 1
if temp_number == 1:
ugly_numbers_found += 1
current_number += 1
# current_number was incremented one last time, we must return the number before incrementing
return current_number - 1To find ugly numbers efficiently, we build them from the ground up using only the prime factors 2, 3, and 5. We progressively multiply existing ugly numbers by these prime factors to generate new, larger ugly numbers, ensuring we only consider numbers divisible by these primes.
Here's how the algorithm would work step-by-step:
def find_ugly_number(nth_ugly_number):
ugly_numbers = [1]
index_for_multiple_of_2 = 0
index_for_multiple_of_3 = 0
index_for_multiple_of_5 = 0
while len(ugly_numbers) < nth_ugly_number:
next_multiple_of_2 = ugly_numbers[index_for_multiple_of_2] * 2
next_multiple_of_3 = ugly_numbers[index_for_multiple_of_3] * 3
next_multiple_of_5 = ugly_numbers[index_for_multiple_of_5] * 5
# Find the minimum of the next multiples.
next_ugly_number = min(next_multiple_of_2, next_multiple_of_3, next_multiple_of_5)
ugly_numbers.append(next_ugly_number)
# Increment the indices for the multiples.
if next_ugly_number == next_multiple_of_2:
index_for_multiple_of_2 += 1
if next_ugly_number == next_multiple_of_3:
index_for_multiple_of_3 += 1
# Avoid duplicates, so increment if equal.
if next_ugly_number == next_multiple_of_5:
index_for_multiple_of_5 += 1
# Return the nth ugly number.
return ugly_numbers[-1]| Case | How to Handle |
|---|---|
| Input n is zero | Return 1, as the first ugly number is conventionally defined as 1. |
| Input n is negative | Throw an IllegalArgumentException, as the definition of ugly numbers does not include negative numbers. |
| Input n is 1 | Return 1, as 1 is the first ugly number. |
| Large input n leading to integer overflow during calculation | Use long data type instead of int to prevent integer overflow. |
| Extreme case where only one prime factor is used repeatedly. | The algorithm correctly handles cases with skewed prime factor usage, like 2*2*2*2...*2. |
| Input where n is close to the maximum integer value. | Ensure array or list storing ugly numbers does not exceed available memory. |
| Generating a very large number of ugly numbers exceeding available memory | The algorithm must be optimized for memory efficiency, potentially using generators or limiting the size of the generated list. |
| Division by zero if prime factors array contains zero | Validate prime factors array for zero values, and throw exception if found. |