package 丑数;
/**
* 题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。
* 求按从小到大的顺序的第1500个丑数。
* 例如6、8都是丑数,但14不是,因为它包含因子7。
* 习惯上我们把1当做第一个丑数。
*/
public class Solution {
//暴力遍历求解
public static boolean isUgly(int number) {
while (number % 2 == 0)
number /= 2;
while (number % 3 == 0)
number /= 3;
while (number % 5 == 0)
number /= 5;
return number == 1 ? true : false;
}
public static int getUglyNumberA(int index) {
int cnt = 0;
int number = 0;
while (cnt < index) {
if (isUgly(++number)) { //是丑数
++cnt;
}
}
return number;
}
/**
* 我们所寻找的丑数都可以通过某一个丑数乘以2、3、5得到,
* 所以我们只需要将计算获得的丑数依次保存到数组中。
* 计算规则:
* 从1开始,每一个丑数都要成以2、3、5,
* 用3个下标记录变量,分别用来记录下一轮乘以2、3、5的丑数,
* 将计算得到第一个大于数组中最大丑数的结果保存到丑数数组中,
* 然后将该轮计算结果都等于数组中最大丑数的数的对应下标变量都加一。(不用小于等于)
* @param index
* @return 返回丑数数组中的最后一个数
*/
public static int getUglyNumberB(int index) {
int[] uglyArray = new int[index];
uglyArray[0] = 1;
int min = 0;
int multiply2 = 0;
int multiply3 = 0;
int multiply5 = 0;
//通过for循环往数组里面填充丑数
for (int i = 1; i < index; ++i) {
min = Math.min(Math.min(uglyArray[multiply2] * 2, uglyArray[multiply3] * 3),
uglyArray[multiply5] * 5);
uglyArray[i] = min;
if (uglyArray[multiply2] * 2 == uglyArray[i])
++multiply2;
if (uglyArray[multiply3] * 3 == uglyArray[i])
++multiply3;
if (uglyArray[multiply5] * 5 == uglyArray[i])
++multiply5;
}
return uglyArray[index - 1];
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
System.out.println("getUglyNumberA:" + getUglyNumberA(1500));
long endTime = System.currentTimeMillis();
System.out.println("运行时间:" + (endTime-startTime));
startTime = System.currentTimeMillis();
System.out.println("getUglyNumberB:" + getUglyNumberB(1500));
endTime = System.currentTimeMillis();
System.out.println("运行时间:" + (endTime-startTime));
}
}
getUglyNumberA:859963392
运行时间:10418
getUglyNumberB:859963392
运行时间:0
Process finished with exit code 0