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.
这也是今天新加的一道题。挺有意思的。~
这道题如果找不到方法的话会很难,但是也不是太难,只能说算法会很复杂。这里还是需要借助一些数学知识。
这道题的思路借鉴于:http://www.geeksforgeeks.org/ugly-numbers/
经过观察ugly number sequence,我们发现其实可以将这个sequence分解为三个小的sequence。(因为一共三个prime factor嘛)
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, …
(1) 1×2, 2×2, 3×2, 4×2, 5×2, …
(2) 1×3, 2×3, 3×3, 4×3, 5×3, …
(3) 1×5, 2×5, 3×5, 4×5, 5×5, …
我觉得经过观察上面这三个sequence,应该大家可以找到规律了。
每一个分解出来的sequence就等于原来的ugly number sequence中的每个数乘以2/3/5。
因此我们可以用merge sort依次从这三个分解出的sequence里面依次挑出ugly number。借助Math.min()method。
代码如下。~
public class Solution { public int nthUglyNumber(int n) { int[] result=new int[n]; result[0]=1; int a=0; int b=0; int c=0; int factora=2; int factorb=3; int factorc=5; for(int i=1;i<n;i++){ int min=Math.min(Math.min(factora,factorb),factorc); result[i]=min; if(factora==min){ factora=2*result[++a]; } if(factorb==min){ factorb=3*result[++b]; } if(factorc==min){ factorc=5*result[++c]; } } return result[n-1]; } }