描述
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.
找出第n个丑数
这道题是之前那道Ugly Number 丑陋数的延伸,这里让我们找到第n个丑陋数,还好题目中给了很多提示,基本上相当于告诉我们解法了,根据提示中的信息,我们知道丑陋数序列可以拆分为下面3个子列表:
(1) 1x2, 2x2, 2x2, 3x2, 3x2, 4x2, 5x2…
(2) 1x3, 1x3, 2x3, 2x3, 2x3, 3x3, 3x3…
(3) 1x5, 1x5, 1x5, 1x5, 2x5, 2x5, 2x5…
[1] index2*2系列
[2] index3*3 系列
[3] index5*5 系列
链表合并系列, 三个连标合并系列,
这个过程就好像是合并三个链表这种情况,
public int nthUglyNumber(int n) {
int[] uglyNumbers = new int[n];
uglyNumbers[0] = 1;
// System.out.println("uglyNumbers[0]:1");
int idx2 = 0;
int idx3 = 0;
int idx5 = 0;
int counter = 1;
while (counter < n) {
// System.out.println("-----------");
// System.out.println("idx2:" + idx2 + ";ugly[idx2]:" + uglyNumbers[idx2]);
// System.out.println("idx3:" + idx3 + ";ugly[idx3]:" + uglyNumbers[idx3]);
// System.out.println("idx5:" + idx5 + ";ugly[idx5]:" + uglyNumbers[idx5]);
// System.out.println("idx2:" + idx2 + ";idx3:" + idx3 + ";idx5:" + idx5);
int min = minOf(
uglyNumbers[idx2] * 2,
uglyNumbers[idx3] * 3,
uglyNumbers[idx5] * 5);
if (min == uglyNumbers[idx2] * 2) {
// System.out.println("min==ugly[idx2]*2:" + uglyNumbers[idx2] * 2);
// System.out.println("idx2:" + idx2 + "→" + (idx2 + 1));
idx2++;
}
if (min == uglyNumbers[idx3] * 3) {
// System.out.println("min==ugly[idx3]*3:" + uglyNumbers[idx3] * 3);
// System.out.println("idx3:" + idx3 + "→" + (idx3 + 1));
idx3++;
}
if (min == uglyNumbers[idx5] * 5) {
// System.out.println("min==ugly[idx5]*5:" + uglyNumbers[idx5] * 5);
// System.out.println("idx5:" + idx5 + "→" + (idx5 + 1));
idx5++;
}
uglyNumbers[counter] = min;
// System.out.println("uglyNumbers[" + counter + "]:" + min);
counter++;
}
// System.out.println("-----------");
// System.out.println("return:" + uglyNumbers[n - 1]);
return uglyNumbers[n - 1];
}
/**
* 求三个数字中最小的数字
* @param a 数字a
* @param b 数字b
* @param c 数字c
* @return a、b、c中最小的数字
*/
private int minOf(int a, int b, int c) {
int temp = a < b ? a : b;
return temp < c ? temp : c;
}
简化版本代码
“`
class Solution {
public int nthUglyNumber(int n) {
//后验证的方法解决问题
if(n<=0) return 0;
if(n==1) return 1;
int [] result= new int [n];
result[0] =1;
// pointers for 2, 3, 5
int i2=0, i3=0,i5=0;
int factor2 =2, factor3 =3, factor5= 5;
for(int i =1;i<n;++i){
int min = Math.min(Math.min(factor2,factor3), factor5);
result[i] = min;
//更新最后一个序列的数据,
if(result[i] == factor2)
//在这里result[++index]代表的是上一个数据的值
factor2 = result[++i2] *2;
if(result[i] ==factor3)
factor3 = result[++i3] *3;
if(result[i]==factor5)
factor5 = result[++i5] *5;
}
return result[n-1];
}
initialize
ugly[] = | 1 |
i2 = i3 = i5 = 0;
First iteration
ugly[1] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(2, 3, 5)
= 2
ugly[] = | 1 | 2 |
i2 = 1, i3 = i5 = 0 (i2 got incremented )
Second iteration
ugly[2] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(4, 3, 5)
= 3
ugly[] = | 1 | 2 | 3 |
i2 = 1, i3 = 1, i5 = 0 (i3 got incremented )
Third iteration
ugly[3] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(4, 6, 5)
= 4
ugly[] = | 1 | 2 | 3 | 4 |
i2 = 2, i3 = 1, i5 = 0 (i2 got incremented )
Fourth iteration
ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(6, 6, 5)
= 5
ugly[] = | 1 | 2 | 3 | 4 | 5 |
i2 = 2, i3 = 1, i5 = 1 (i5 got incremented )
Fifth iteration
ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(6, 6, 10)
= 6
ugly[] = | 1 | 2 | 3 | 4 | 5 | 6 |
i2 = 3, i3 = 2, i5 = 1 (i2 and i3 got incremented )
Will continue same way till I < 150