题目
我们把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做第一个丑数。要求给出第k个丑数。
思路
- 思路一,逐一判断每个数字是否是丑数,直到找到第k个丑数
- 思路二,上述思路需要判断每个数字,计算量大。因此思路二提出利用空间换时间的思路。即将已经排序好丑数存在一个数组中,之后的每个丑数都由这个数组中的丑数2或者3或者5得到。
关键在于,如何将这些丑数排序?可以从数组中找到3个丑数T2,T3,T5,这3个丑数满足,T22,T33,T55都刚好比数组中最大的丑数大,则min(T22,T33,T5*5)就是下一个丑数,并存入数组。同时更新T2,T3,T5,使得仍满足上述条件。
测试用例
1.功能测试(2,3,4,5等)
2.特殊测试(0,1)
3…性能测试(1500等)
Java实现
实现一
import java.util.ArrayList;
public class GetUglyNumber_Solution {
public int GetUglyNumber_Solution(int index) {
if (index <= 0) return 0;
int number = 0;
int uglyCount = 0;
while (uglyCount < index) {
number++;
if (isUglyNumber(number)) {
uglyCount++;
}
}
return number;
}
/**
* 判断是否是丑数
* @param num
* @return
*/
public boolean isUglyNumber(int num) {
while (num % 2 == 0) {
num /= 2;
}
while (num % 3 == 0) {
num /= 3;
}
while (num % 5 == 0) {
num /= 5;
}
return num == 1;
}
public static void main(String[] args) {
GetUglyNumber_Solution ugly = new GetUglyNumber_Solution();
int re = ugly.GetUglyNumber_Solution(8);
System.out.println(re);
}
}
实现二
import java.util.ArrayList;
public class GetUglyNumber_Solution {
public int GetUglyNumber_Solution(int index) {
if (index <= 0) return 0;
int number = 0;
ArrayList<Integer> uglyNumList = new ArrayList<>();
uglyNumList.add(1);
ArrayList<Integer> uglyNumList2 = uglyNumList;
ArrayList<Integer> uglyNumList3 = uglyNumList;
ArrayList<Integer> uglyNumList5 = uglyNumList;
number++;
int index2 = 0, index3 = 0, index5 = 0;
while (number < index) {
int min = minMulti(uglyNumList2.get(index2) * 2, uglyNumList3.get(index3) * 3, uglyNumList5.get(index5) * 5);
uglyNumList.add(min);
while (uglyNumList2.get(index2) * 2 <= uglyNumList.get(number)) {
index2++;
}
while (uglyNumList3.get(index3) * 3 <= uglyNumList.get(number)) {
index3++;
}
while (uglyNumList5.get(index5) * 5 <= uglyNumList.get(number)) {
index5++;
}
number++;
}
return uglyNumList.get(index - 1);
}
public int minMulti(int a, int b, int c) {
int min = (a < b) ? a : b;
min = (min < c) ? min : c;
return min;
}
public static void main(String[] args) {
GetUglyNumber_Solution ugly = new GetUglyNumber_Solution();
int re = ugly.GetUglyNumber_Solution(8);
System.out.println(re);
}
}
收获
利用丑数性质,在消耗有限空间下,大大减少时间消耗。