剑指 Offer 49. 丑数

我们把只包含质因子 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]
};

你可能感兴趣的:(LeetCode刷题)