算法题解-丑数2

116 阅读2分钟

题目

给你一个整数 n ,请你找出并返回第 n 个 丑数 。

输入: n = 10
输出: 12

题解

第一种

我们在函数中创建了一个长度为n的数组ans,并将第一个数设置为1,接下来我们通过三个指针i2、i3、i5,分别指向当前已知的最小丑数乘以2、3、5的位置,在每次循环中,我们将三个指针所指的数分别乘以2、3、5得到三个候选数a、b、c,并从中选取最小值min,如果最小值为a,我们则将i2指针加1,如果最小值为b,我们则将i3指针加1,如果最小值为c,我们则将i5指针加1,最后我们将最小值min存入ans数组中,并返回第n个丑数即可

var nthUglyNumber = function(n) {
  const ans = new Array(n);
  ans[0] = 1;
  for (let i2 = 0, i3 = 0, i5 = 0, index = 1; index <= n; index++) {
    let a = ans[i2] * 2,
        b = ans[i3] * 3,
        c = ans[i5] * 5;
    const min = Math.min(a, b, c);
    if (min === a) i2++;
    if (min === b) i3++;
    if (min === c) i5++;
    ans[index] = min;
  }
  return ans[n-1];
};

第二种

我们先声明了一个数组dp用于存储计算得到的丑数,然后我们在声明了一个数组num,这其中包含了因子2、3和5,我们接下来声明了一个变量len表示因子数组num的长度,然后我们将dp[0]初始化为0,dp[1]为1,然后我们在声明了一个数组k,数组k用于记录每个因子对应的指针位置,我们将k数组的元素初始化为1,这里表示初始指针位置为1,然后我们声明了变量t用于临时存储计算得到的丑数,接下来我们使用两个嵌套的循环来计算第2到第n个丑数,外层循环从2开始,到n结束,内层循环用于遍历因子数组num,计算每个因子对应的丑数,我们在内层循环中,首先将t初始化为dp[k[j]]乘以num[j]的值,也就是当前因子对应的丑数,然后我们判断t是否比dp[i]大且比dp[i-1]小,如果是我们则更新dp[i]为t,这样可以确保计算得到的丑数是递增的,然后我们再次遍历因子数组num,我们这里判断是否存在丑数等于t,如果存在我们则将对应的指针位置k[j]加1,因为下一个丑数需要使用下一个因子,最后返回dp[n]即可

var nthUglyNumber = function (n) {
  var dp = []
  var num = [2, 3, 5]
  var len = num.length
  dp[0] = 0
  dp[1] = 1
  var k = [1, 1, 1]
  var t
  for (var i = 2; i <= n; i++) {
    dp[i] = Number.MAX_VALUE
    for (var j = 0; j < len; j++) {
      t = dp[k[j]] * num[j]
      if (dp[i] > t && t > dp[i - 1]) {
        dp[i] = t
      }
    }
    for (var j = 0; j < len; j++) {
      if (dp[i] === dp[k[j]] * num[j]) {
        k[j]++
      }
    }
  }
  return dp[n]
}

坚持努力,无惧未来!