题目
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路
只包含质因子2、3和5的数,那么换句话说就是,只能被2、3、5整除的数叫做丑数。
那么:丑数 = 2^x + 3^y + 5^z
方法一
暴力求解。但是,效率非常低下,往往不能AC题
RUNTIME代码
public class Solution {
public int GetUglyNumber_Solution(int index) {
int sum = 1;
if(index == 0)
return 0;
for(int i = 2 ; ; i++) {
int t = i;
while(t % 2 == 0) {
t /= 2;
}
while(t % 5 == 0) {
t /= 5;
}
while(t % 3 == 0) {
t /= 3;
}
if(t == 1)
sum++;
if(sum == index) {
//System.out.println(i);
return i;
}
}
}
}
方法二
经过方法一的沉淀,我们就试想,操作每一个数进行判断效率低下,那么我们只操作丑数呢?会怎么样?答案不言而喻是翻天覆地的变化。
- 对于2来说,那么就是:2,4,6,8,10,…
- 对于3来说,那么就是:3,6,9,12,15,…
- 对于5来说,那么就是:5,10,15,20,25,…
综上所诉,我们就只需要依次数这里面个数即可。但一定要满足从小到大,因此这里可以用抽象的队列去理解该方法。
- 当该数满足就提取,这三个2、3、5当前位置的最小值存放进去,相对应的下标就要加1
- 如果出现多个最小值相同情况,相对应的下标都要加1
AC代码
public class Solution {
public int GetUglyNumber_Solution(int index) {
if(index == 0)
return 0;
int[] a = new int[index];
a[0]= 1;
int t1 = 0;
int t2 = 0;
int t3 = 0;
for (int i = 1; i < index; i++) {
a[i] = min(a[t1] * 2, a[t2] * 3, a[t3] * 5);
if(a[t1] * 2 == a[i])
t1++;
if(a[t2] * 3 == a[i])
t2++;
if(a[t3] * 5 == a[i])
t3++;
}
System.out.println(a[index - 1]);
return a[index - 1];
}
public int min(int a, int b, int c) {
return a > b ? (b > c ? c : b) : (a > c ? c : a);
}
}