题目描述:
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路一:逐个判断每个整数是不是丑数的解法,直观但不高效(牛客网测试超时)
所谓一个数m是另一个数n的因子,是指n能被m整数,也就是n%m==0。根据丑数的定义,丑数只能被2、3和5整数。也就是说如果一个数能被2整除,我们就把它连续除以2;如果能被3整数,就连续除以3;如果能被5整除,就除以连续5。如果最后我们得到的数字是1,那么这个数就是丑数,否则不是。该算法非常直观,代码也非常简洁,但
最大的问题是每个整数都需要计算。即使一个数字不是丑数,我们还是需要对它做求余和除法操作
。因此该算法的时间效率不够高,面试官也不会就此满足。
思路二:创建数组保存已找到的丑数,用空间换时间的解法
前面的算法之所以效率低,很大程度上是因为不管一个数是不是丑数,我们对它都要作计算。接下来我们试着找到一种只要计算丑数的方法,而不在非丑数的整数上浪费时间。
代码:
1 public class Solution { 2 public int GetUglyNumber_Solution(int index) { 3 if (index == 0) return 0; 4 int[] res = new int[index]; 5 res[0] = 1; 6 int i2,i3,i5; 7 i2 = i3 = i5 = 0; 8 for (int i = 1;i < index;i ++) { 9 res[i] = Math.min(res[i2] * 2, Math.min(res[i3] * 3, res[i5] * 5)); 10 if (res[i] == res[i2] * 2) i2 ++; 11 if (res[i] == res[i3] * 3) i3 ++; 12 if (res[i] == res[i5] * 5) i5 ++; 13 } 14 return res[index - 1]; 15 } 16 }