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 is typically treated as an ugly number.
n does not exceed 1690.
二、题解
(1) 超级暴力
privatebooleanisUgly(int num){while(num %2==0)
num >>=1;while(num %3==0)
num /=3;while(num %5==0)
num /=5;return num ==1;}/**
* 暴力求解 超时
* @param n
* @return
*/publicintnthUglyNumber1(int n){int ans=1;for(int cnt =1; cnt < n; cnt++){
ans++;if(isUgly(ans))++cnt;}return ans;}
(2) 暴力优化
/**
* 暴力优化
* 为什么用TreeSet会超时??
* 执行用时 353 ms 击败了 5% 的java用户
* 内存消耗 36 MB 击败了 22.5% 的java用户
* @param n
* @return
*/publicintnthUglyNumber2(int n){
ArrayList<Integer> uglyNumList =newArrayList<>();int[] factors ={2,3,5};
uglyNumList.add(1);while(uglyNumList.size()< n){int min = Integer.MAX_VALUE;for(int num : uglyNumList){for(int f : factors){int t = num * f;// 丑数 1074954240 与 5 相乘得到1079803904 会溢出,所以要增加一层判断t / num == fif(t < min && t > uglyNumList.get(uglyNumList.size()-1)&& t / num == f)
min = t;}}
uglyNumList.add(min);}return uglyNumList.get(n-1);}
(3) 三重循环暴力
/**
* 优化暴力:去重,不难发现如果将一个丑数乘以2/3/5,得到的还是丑数,
* 但这样计算可能会出现重复的结果。比如2*3=6,3*2=6
*
* 我们将丑数的每个循环都乘以2/3/5,这样得到的
*
* @param n
* @return
*/publicintnthUglyNumber3(int n){
ArrayList<Integer> uglyNumList =newArrayList<>(n);for(long i =1; i < Integer.MAX_VALUE; i<<=1)for(long j = i; j < Integer.MAX_VALUE; j*=3)for(long k = j; k < Integer.MAX_VALUE; k*=5)
uglyNumList.add((int)k);
Collections.sort(uglyNumList);return uglyNumList.get(n-1);}