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.
思路: 可以逐个判断每个整数是不是丑数,但是还不够高效。根据丑树的定义,丑数应该是另一个丑数乘以2、3或者5的结果。然后我们可以专门用一个数组来存储已有的丑数,关键是怎么把所有的丑数按照升序存在数组中,考虑一下怎么计算下一个丑数,先记录下此时数组中最大的丑数M,用当前数组中每一个丑数乘以2得到第一个比M大的数为止计为a,用当前数组中每一个丑数乘以3得到第一个比M大的数为止,计为b,每一个丑数乘以5得到第一个比M大的数为止,计为c,那么下一个按照升序排列的应该存在数组中的应该是a,b,c中最小的一个。
但是也不用每一次都用数组中的每一个丑数乘以2、3或者5,因为已有的丑数是按照顺序存在数组中的。对乘以2而言,肯定存在某一个丑数T2,排在T2之前的每一个丑数乘以2得到的结果都会小于已有的最大丑数,在它之后的每一个丑数乘以2得到的结果都会太大,我们只需记下这个丑数的位置,同时每次生成新的丑数的时候去更新这个T2,。对于乘以3和5而言,也存在同样的T3和T5.
public class Solution {
public int nthUglyNumber(int n) {
if(n<1) return -1;
int[] nums=new int[n];
int u2=0;
int u3=0;
int u5=0;
nums[0]=1;
int next=1;
while(next<n)
{
int min=Math.min(Math.min(nums[u2]*2,nums[u3]*3),nums[u5]*5);
nums[next]=min;
while(u2<=next && nums[u2]*2<=nums[next])
{
u2++;
}
while(u3<=next && nums[u3]*3<=nums[next])
{
u3++;
}
while(u5<=next && nums[u5]*5<=nums[next])
{
u5++;
}
next++;
}
return nums[n-1];
}
}