我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)
求按从小到大的顺序的第 n 个丑数。
出看这道题可能感觉能算,但是思路就非常繁琐。
这个只说说思路,既然2,3,5是该数的因子,那么该数除以2,3,5的余数一定是 0 ,那么就让每个数连续除以2,3,5,只到余数不为0 ,结果是1的就是丑数,在比较各个丑数的大小,取出我们想要的那个丑数。
(看看就行~~~ )
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。
习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
可能刚开始没看懂题意,这里解释一下
1是丑数,然后是质因数为2,3,5的数
就是说4是两个丑数2相乘得到的一个丑数
6是2*3的到的丑数
8是2*4得到的丑数
就是说丑数是由前面的一个丑数乘以2或3或5得到的。
题解:如何得到前一个丑数那,
存放丑数数组res,res数组里的第一个元素为1。因为我们要让丑数数列有序,所以要每次使这三个因子组成的最小的数进入数组。
t2表示乘以2得到的丑数,t3表示乘以3得到的丑数,t5是乘以5得到的丑数,
把最小的进入丑数数组arr
res: 1
t2: 2
t3: 3
t5: 5
比较(2,3,5)->min_n = 2, 2进入 arr
res:1 2
t 2: 4
t 3: 3 6
t 5: 5 10
然后比较当前的值(4,3,5),3再进入arr
res 1 2 3
t 2: 4
t 3: 6 9
t 5: 5 10
(4, 5, 6) 得到4进入arr
····
知道目标数组的最后一位出现,我们将最后一个值返回。
/**
* @param {number} n
* @return {number}
*/
var nthUglyNumber = function(n) {
//创建个数为n的数组
let arr = new Array(n).fill(0);
//第一个元素是1(丑数的规定)
arr[0] = 1;
//定义三个指针(分别让他们*2,*3,*5)找出相对较小的
let p1 = 0,
p2 = 0,
p3 = 0;
for (let i = 1; i < n; i++) {
//最后一个丑数就是我们想要的丑数
lastarr = arr[i - 1];
while (lastarr >= arr[p1] * 2) p1++;
while (lastarr >= arr[p2] * 3) p2++;
while (lastarr >= arr[p3] * 5) p3++;
//比较三数大小,把最小的数放入目标数组arr
arr[i] = Math.min(Math.min(arr[p1] * 2, arr[p2] * 3), arr[p3] * 5)
}
// console.log(arr[n-1])
return arr[n - 1]
};