- 丑数的概念
某一个数只包含质因数2,3,5,则该数为丑数。换一句话来说,就是,某一个能被2整除、或者被3整除、或者被5整除之外,不能再被其他数整除,则为丑数。如6,能被2整除和被3整除;8,能一直被2整除,9能一直被3整除。
- 时间效率高的思路
建立一个空的数组,用来存放排好序的丑数;这会牺牲小部分的空间内存。
那么具体怎么实现丑数的排序呢?
假设已经有一个排好序的丑数数组M,那么我们要如何寻找下一个丑数呢?我们知道,这个丑数一定是前面排好序的丑数分别*2、*3、*5的结果之中的一个,我们要找到这些结果之中的最小的丑数,这个丑数就是下一个丑数。但是如果这样找的话,当前面的丑数数量很大时,则效率十分低下。
我们可以在排好序的丑数数组M中,找到一个数,这个数之前的所有数×2都会小于或等于当前最大的丑数max,这个数之后的数×2又会大的多,我们将这个数的位置记为T2;例如有一排好序的丑数数组[1,2,3,4,5,6,8];我们要找到8后面的一个丑数,观察数组发现,5之前的数乘以2都小于等于8;而5之后的数乘以2又比8大得多,因此5对应的索引就是我们要找的T2,同理找出T3,T5;比较T2×2、T3×3、T5×5,找出最小的数,则是下一个丑数。
代码实现:
function GetUglyNumber_Solution(index)
{
if(index<=0) {
return 0;
}
var number = [];
number[0] = 1;
var nextUglyIndex = 1;
var T2=0,T3=0,T5=0;
while(nextUglyIndex<index) {
var min = Math.min(number[T2]*2,number[T3]*3,number[T5]*5);
number[nextUglyIndex] = min;
while(number[T2]*2<=number[nextUglyIndex]) {
T2++;
}
while(number[T3]*3<=number[nextUglyIndex]) {
T3++;
}
while(number[T5]*5<=number[nextUglyIndex]) {
T5++;
}
nextUglyIndex++;
}
var res = number[nextUglyIndex-1];
number = null; //找到后收回新开辟的内存,节省内存空间
return res;
}