《剑指offer》刷题——【时间效率与空间效率的平衡】面试题49:丑数(java实现)
一、题目描述
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它
包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
二、题目分析
方法一:逐个判断每个整数是不是丑数
- 丑数:只能被2,3,5整除的数
- 按顺序判断每个整数是不是丑数
- 判断丑数:连续除以2,连续除以3,连续除以5;若最后得到1,则为丑数
方法二:借助数组保存已找到的丑数,空间换时间
- 借助大小为N的数组,此数组存放排好序的丑数(每个丑数都是前面的丑数乘以2,3,5得到)
- 如何确保数组里丑数排好序:
- 假设已有若干排好序的丑数,其中最大设为M
- 下一个丑数:
- 把已有的每个丑数 x 2,得到若干 < = >M的丑数
- 小于等于的已经在数组中,不用考虑
- 找到大于M的数中最小的数字,作为下一个丑数
- x2、x3、x5大于M的数分别记为M2,M3,M5,则下一个数字为这三者中最小的一个
- 不用把已有的丑数每个都乘以2,3,5,记录通过x2得到的最大的丑数位置,x3,x5的位置上亦是如此,以后确定下一个丑数只需从标记的三个位置的数乘以2,3,5
三、代码实现
public class Solution {
private int[] data = new int[1500];
public int GetUglyNumber_Solution(int index) {
if(index<=0)
return 0;
data[0]=1;
int i2 = 0;
int i3 = 0;
int i5 = 0;
int currentIndex = 1;
int next = data[0];
while(currentIndex < index){
next = min(data[i2]*2, data[i3]*3, data[i5]*5);
if(data[i2]*2 <= next){
i2++;
}
if(data[i3]*3 <= next){
i3++;
}
if(data[i5]*5 <= next){
i5++;
}
data[currentIndex++] = next;
}
return next;
}
public int min(int a, int b, int c){
int min = a<b? a:b;
min = min < c? min:c;
return min;
}
}