## Description

Write a program to find the n-th ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5.

Example:

Input: n = 10
Output: 12
Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.


Note:

1. 1 is typically treated as an ugly number.
2. n does not exceed 1690.

## Solutions

### 1. Brute Force

如果直接遍历所有数，并判断每个数是不是丑数，这样就太多重复了，累加时有无效数算是一种重复，再判断每一个数是否为丑数就需要除和取余，又是一种重复，其实可以用之前的已知的丑数，在其基础上乘2、3、5 就好了。

# Time: O(n^3)
# Space: O(n)
class Solution:
def nthUglyNumber(self, n: int) -> int:
if n <= 0:
return 0
INT_MAX = 2**32-1
ugly_nums = []
t2 = t3 = t5 = 1
while t2 <= INT_MAX:
t3 = t2
while t3 <= INT_MAX:
t5 = t3
while t5 <= INT_MAX:
ugly_nums.append(t5)
t5 *= 5
t3 *= 3
t2 *= 2
ugly_nums.sort()
return ugly_nums[n-1]

# 596/596 cases passed (292 ms)
# Your runtime beats 20.29 % of python3 submissions
# Your memory usage beats 100 % of python3 submissions (12.8 MB)


### 2. DP

# Time: O(n)
# Space: O(n)
class Solution:
def nthUglyNumber(self, n: int) -> int:
if n <= 0:
return 0
ugly_nums = [1]
i2, i3, i5 = 0, 0, 0
for _ in range(n):
next2 = ugly_nums[i2] * 2
next3 = ugly_nums[i3] * 3
next5 = ugly_nums[i5] * 5
next = min(next2, next3, next5)
if next == next2:
i2 += 1
if next == next3:
i3 += 1
if next == next5:
i5 += 1
ugly_nums.append(next)
return ugly_nums[n-1]

# 596/596 cases passed (128 ms)
# Your runtime beats 87.68 % of python3 submissions
# Your memory usage beats 100 % of python3 submissions (12.6 MB)