package pers.lyt.java;
//题目:丑数
// 把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。
//例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做第一个丑数。
// 习惯上我们把1当做是第一个丑数。1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24。
public class Offer49_UglyNumber {
/**
* 解法一:逐个判断每个整数是不是丑数的解法,直观但不够高效(暴力法)
*/
public int getUglyNumber_Solution1(int index) {
if (index <= 0)
return 0;
int number = 0;
int uglyFound = 0; // 表示第几个丑数
while (uglyFound < index) {
number++;
if (isUgly(number)) {
uglyFound++;
}
}
return number;
}
public boolean isUgly(int number) {
while (number % 2 == 0)
number = number / 2;
while (number % 3 == 0)
number = number / 3;
while (number % 5 == 0)
number = number / 5;
return number == 1;
}
/**
* 解法二:空间换时间,利用一个数组来保存前面已经找到的丑数,再依次得到后面的丑数,
* 这样就可以直接跳过那些不是丑数的数,不用每一个数都去判断。
* num1,num2,num3 min mul2,mul3,mul5
* ugly[0] 1 0 0 0
* 2、3、5 2 1 0 0
* 4、3、5 3 1 1 0
* 4、6、5 4 2 1 0
* 6、6、5 5 2 1 1
* 6、6、10 6 3 2 1
* 8、9、10 8 4 2 1
*/
public int getUglyNumber_Solution2(int index) {
if (index <= 0)
return 0;
int[] uglyArray = new int[index];
uglyArray[0] = 1; // 第一个丑数默认为1
int multiply2 = 0;
int multiply3 = 0;
int multiply5 = 0;
for (int i = 1; i < index; i++) {
int min = min(uglyArray[multiply2] * 2, uglyArray[multiply3] * 3, uglyArray[multiply5] * 5);
uglyArray[i] = min;
while (uglyArray[multiply2] * 2 == uglyArray[i]) {
multiply2++;
}
while (uglyArray[multiply3] * 3 == uglyArray[i]) {
multiply3++;
}
while (uglyArray[multiply5] * 5 == uglyArray[i]) {
multiply5++;
}
}
return uglyArray[index - 1];
}
/**
* 因为要保证丑数数组是从小到大排序的,每一个都要比较一下三个值,取最小值放入数组中,
* 然后再更新这个最小值。
*/
private int min(int number1, int number2, int number3) {
int min = (number1 < number2) ? number1 : number2;
return (min < number3) ? min : number3;
}
public static void main(String[] args) {
Offer49_UglyNumber demo = new Offer49_UglyNumber();
int number1 = demo.getUglyNumber_Solution1(1500);
int number2 = demo.getUglyNumber_Solution2(1500);
System.out.println(number1 + " " + number2);
}
}
49_UglyNumber
最新推荐文章于 2024-03-31 10:09:12 发布