目录
题目描述
我们把只包含 质因子2、3和5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 N 个丑数。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。(时间限制1s)
测试用例
- 功能测试(输入2、3、4、5、6等)
- 特殊输入测试(边界值1;无效输入0)
- 性能测试(输入较大的数字,如1500)
题目考点
- 考察应聘者对时间复杂度的理解。
- 考察应聘者的学习能力和沟通能力,当应聘者听到不熟悉的概念之后,要有主动积极的态度,大胆向面试官提问。
解题思路
1、直接解题:不管一个数是不是丑数,都对它进行计算,时间效率低。
2、空间换时间:
1)、首先,由已知丑数得未知丑数的方法:根据丑数的定义,丑数应该是另一个丑数乘以2、3或者5的结果(1除外)。
2)、因此,构建数组保存已知丑数,并且按照1中规律产生新丑数,最后按照规律(从小到大存放)将新丑数存入数组。
直接解题
/**
* 丑数
*
*/
public class Solution {
/**
* 求出第index个丑数
*/
public int getUglyNumber_Solution(int index) {
// 异常
if (index <= 0) {
return 0;
}
int count = 0;
int base = 0;
while (count != index) {
base++;
if (isUglyNumber(base)) {
count++;
}
}
return base;
}
/**
* 判断是否为丑数
* @param number
* @return
*/
boolean isUglyNumber(int number) {
while (number % 2 == 0) {
number /= 2;
}
while (number % 3 == 0) {
number /= 3;
}
while (number % 5 == 0) {
number /= 5;
}
return number == 1;
}
}
参考解题
public class Solution {
// 按照从小到大顺序求出第index个丑数
// 空间换时间
public int GetUglyNumber_Solution(int index) {
// 异常
if(index <= 0){
return 0;
}
// 按照顺序存放所有丑数
int[] dp = new int[index];
dp[0] = 1;
int nextUglyIndex = 1;
// 存储乘以2、3、5 的下标
int i2 = 0, i3 = 0, i5 = 0;
// 保证数组排序,由已知丑数得新丑数
while(nextUglyIndex < index){
int min = Math.min(Math.min(dp[i2] * 2, dp[i3] * 3), dp[i5] * 5);
dp[nextUglyIndex] = min;
if(dp[i2] * 2 == min){
i2++;
}
if(dp[i3] * 3 == min){
i3++;
}
if(dp[i5] * 5 == min){
i5++;
}
nextUglyIndex++;
}
return dp[index - 1];
}
}
补充
空间和时间要求可以咨询面试官