问题链接:https://leetcode.com/problems/ugly-number-ii/?tab=Description
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, and n does
not exceed 1690.
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).
最直接的想法是挨个判断,每找到一个索引加1,直到索引等于n,但是Time Limit Exceeded
public class Solution {
public int nthUglyNumber(int n) {
int index=0;
int num=1;
for(;;) {
if(isUglyNum(num)) {
index++;
}
if(index==n)
return num;
num++;
}
}
private boolean isUglyNum(int num) {
while(num%2==0) num/=2;
while(num%3==0) num/=3;
while(num%5==0) num/=5;
return num==1;
}
}
根据提示大致有了思路,如果一个数是丑数,那么它与2、3、5的乘积也是丑数,则只要设置一个数组和三个指针位置,分别从0开始,数组元素与2、3、5的乘积从小到大都要加入数组中,直到数组中元素个数和n相等。做法如下:
1.设置i、j、k三个指针,初始值均为0;
2.uglyArray[i]*2、uglyArray[j]*3、uglyArray[k]*5中的最小值即为丑数数组的下一个元素,并将最小值对应的下标指针+1,若多个值均为最小值,则都要进行更新,表示当前元素在2、3、5乘积队列已使用过;
3.当数组中丑数个数增长到n个时,循环结束,uglyArray[n-1]即为要求;
public class Solution {
public int nthUglyNumber(int n) {
if(n<=0) return 0;
int i=0,j=0,k=0;
int[] uglyNums = new int[n];
int count = 1;
uglyNums[0] = 1;
while(count < n) {
int num = min(uglyNums[i]*2,uglyNums[j]*3,uglyNums[k]*5);
if(num==uglyNums[i]*2) i++;
if(num==uglyNums[j]*3) j++;
if(num==uglyNums[k]*5) k++;
uglyNums[count++]=num;
}
return uglyNums[n-1];
}
private int min(int a,int b,int c) {
int t = (a<b?a:b);
return t<c?t:c;
}
}
参考文档:https://my.oschina.net/Tsybius2014/blog/495962