Ugly Number II
Problem
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 first 10
ugly numbers.
Note that 1
is typically treated as an ugly number.
Hint:
- The naive approach is to call isUgly for every number until you reach the nth one. Most numbers are not ugly. Try to focus your effort on generating only the ugly ones.
- An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number.
- The key is how to maintain the order of the ugly numbers. Try a similar approach of merging from three sorted lists: L1, L2, and L3.
- Assume you have Uk, the kth ugly number. Then Uk+1 must be Min(L1 2, L2 3, L3 * 5).
Solution
public class Solution {
public int nthUglyNumber(int n) {
int index2 = 0, index3 = 0, index5 = 0;
int exp2 = 2, exp3 = 3, exp5 = 5;
int[] ugly = new int[n];
ugly[0] = 1;
for (int i = 1; i < n; i++) {
int num = Math.min(Math.min(exp2, exp3), exp5);
ugly[i] = num;
if (num == exp2) exp2 = 2 * ugly[++index2];
if (num == exp3) exp3 = 3 * ugly[++index3];
if (num == exp5) exp5 = 5 * ugly[++index5];
}
return ugly[n-1];
}
}
Analysis
To solve this problem, we need to think about the opposite direction of telling the number is ugly number
Since an ugly number can be constructed only by multiplying 2, 3, or 5
We store the expression list of these numbers called exp2
, exp3
and exp5
Then we use a loop to construct a list of ugly numbers, of course we first set ugly[0] = 1
We get the minimum number of each expression and then update the indices and corresponding expressions
Notice that we cannot use if() else if()
statement while updating because an ugly number can be constructed more than one way
For example, 6 = 2 3 = 3 2 :)